{"record":{"id":"a147872c5fe33914","repo":"amir20/dozzle","slug":"no-container-matching-q-found-across-all-connecte","errorCode":null,"errorMessage":"no container matching %q found across all connected hosts; call find_containers to list available containers","messagePattern":"no container matching %q found across all connected hosts; call find_containers to list available containers","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/tools_resolve.go","lineNumber":63,"sourceCode":"// id or name).\nfunc resolveContainerRef(containerRef, hostRef string, deps ToolDeps) (hostID, containerID string, err error) {\n\ttier, trimmedHostRef, scopedHostID, hostNames, err := matchContainerTier(containerRef, hostRef, deps)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tswitch len(tier) {\n\tcase 0:\n\t\t// No tier matched. When an explicit host was given (and resolved to a\n\t\t// real host id) but the listing produced no match — e.g. a host returned\n\t\t// a partial error and was omitted from ListAllContainers — pass the\n\t\t// reference straight through to FindContainer's direct lookup, exactly as\n\t\t// before this resolver existed. This guarantees id-based callers never\n\t\t// regress.\n\t\tif scopedHostID != \"\" {\n\t\t\treturn scopedHostID, strings.TrimSpace(containerRef), nil\n\t\t}\n\t\treturn \"\", \"\", fmt.Errorf(\"no container matching %q found across all connected hosts; call find_containers to list available containers\", strings.TrimSpace(containerRef))\n\tcase 1:\n\t\treturn tier[0].Host, tier[0].ID, nil\n\tdefault:\n\t\t// Multiple matches. The usual benign cause is Docker Swarm (or plain\n\t\t// restart churn) leaving stopped task containers behind across redeploys\n\t\t// — the short name \"svc.1\" substring-matches every historical\n\t\t// \"svc.1.<taskid>\" corpse alongside the one live task. When exactly one\n\t\t// candidate is running it is the unambiguous live referent, so resolve to\n\t\t// it rather than make the caller hunt for an id. We still refuse to\n\t\t// choose between multiple *live* containers — that is the real ambiguity\n\t\t// the write tools must never guess at.\n\t\tif live := runningContainers(tier); len(live) == 1 {\n\t\t\treturn live[0].Host, live[0].ID, nil\n\t\t}\n\t\treturn \"\", \"\", ambiguousError(strings.TrimSpace(containerRef), trimmedHostRef, tier, hostNames)\n\t}\n}\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/cloud/tools_resolve.go#L45-L81","documentation":"The strict (write-path) resolver found zero candidate containers across all connected hosts, and no host was scoped, so it refuses with this message pointing callers at find_containers. Write actions never fall back to ambiguous or stopped containers.","triggerScenarios":"Calling executeContainerAction or executeUpdateContainer with a container_id that matches nothing: a typo'd name, an id from a removed container, or a short Swarm task name whose matches are all stopped (stopped corpses are excluded from writes).","commonSituations":"Docker Swarm redeploys leaving old task containers that were later pruned; container removed between discovery and action; case-sensitive name mismatch or missing dev.dozzle.name label.","solutions":["Run find_containers to list available containers and copy the exact id","Use the full container id rather than a name or short prefix","Check the target host is connected (list_hosts); a disconnected host hides its containers","If a stopped container is intended, start it or resolve via the read path first"],"exampleFix":"// before\nrestartContainer({container_id: \"myapp\"})  // no match\n// after\nconst cs = await findContainers({name: \"myapp\"})\nrestartContainer({container_id: cs[0].id})","handlingStrategy":"validation","validationCode":"const cs = await findContainers({}); const match = cs.find(c => c.id === ref || c.name === ref && c.state === 'running'); if (!match) throw new Error('no running container matching ' + ref);","typeGuard":"null","tryCatchPattern":"try { await restartContainer({container_id: ref}) } catch (e) { if (/no container matching/.test(e.message)) { const cs = await findContainers({}); console.warn('candidates:', cs.map(c => c.id)); } }","preventionTips":["Copy ids from find_containers rather than typing names","Remember write actions refuse stopped Swarm corpse containers","Confirm the host is connected before acting"],"tags":["cloud-tools","container-resolution","resource-not-found"],"backgroundTag":"resource-not-found","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}