Why it gets repaired twice
Because the visible symptom and the actual source are frequently at different components, and because each trade naturally examines what it works on. A roofer called to a ceiling stain examines the flashing and the roof; a mason called to the same stain examines the brickwork. If the source is a cracked crown and the roofer replaces the flashing, the flashing is now new and the leak continues. The second call is the one that finds it, and the first bill was for work that was not wrong so much as beside the point.
The diagnosis you can do yourself
Note exactly where the water appears and what weather brings it. A ceiling stain at roof level beside the chimney: flashing. Water in the firebox or standing on the damper after rain: missing or failed cap, or a cracked crown. Damp inside the masonry with white chalky staining on the exterior: crown, almost always. Only in wind from one direction: wind-driven rain reaching one face, which narrows it to that side. Only during snowmelt: possible ice damming forcing water back under the flashing.
Which trade for which finding
Flashing sits at the boundary and either a roofer or a chimney company can do it correctly. What matters is that whoever does it removes any previous tar patch, not adding to it. Crown and cap work is chimney work. Masonry repointing and rebuilding is chimney or mason work. And where the diagnosis is uncertain, the chimney company is commonly the better first call, since they can see the crown and cap from the roof and can also rule out condensation inside the flue, which a roofer cannot.
The cause nobody checks: it might not be a leak
Staining that tracks with appliance use instead of with rain is not a leak at all. It is condensation inside the flue, which happens when an appliance vents into an oversized or unlined chimney and its exhaust cools against cold masonry. It looks like water damage and it behaves completely differently. If your stain appears in cold dry weather when the stove is running hard, no amount of flashing will fix it.