{"record":{"id":"ccdd8974ce083f66","repo":"astrid-runtime/astrid","slug":"capsule-name-was-installed-before-source-track","errorCode":null,"errorMessage":"Capsule '{name}' was installed before source tracking was added. Re-install it manually to record the source.","messagePattern":"Capsule '(.+?)' was installed before source tracking was added\\. Re-install it manually to record the source\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule/install_update.rs","lineNumber":148,"sourceCode":"            &home,\n            &principal,\n            name,\n            workspace,\n            crate::workspace_layout::current(),\n        )?;\n        if !target_dir.exists() {\n            bail!(\"Capsule '{name}' is not installed.\");\n        }\n\n        let meta = read_meta(&target_dir).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"Capsule '{name}' has no meta.json - cannot determine original source. \\\n                 Re-install it manually.\"\n            )\n        })?;\n\n        let source = meta.source.ok_or_else(|| {\n            anyhow::anyhow!(\n                \"Capsule '{name}' was installed before source tracking was added. \\\n                 Re-install it manually to record the source.\"\n            )\n        })?;\n\n        eprintln!(\"Updating {name} from {source}...\");\n        // Re-install exactly the capsule being updated. When `source` is a\n        // monorepo release that ships several `.capsule` assets, pass `name`\n        // as the selector so update refreshes only that one — not every\n        // capsule the release contains.\n        install_capsule_with_options(\n            &source,\n            Some(name),\n            workspace,\n            false,\n            approve_untrusted,\n            &[],\n        )","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule/install_update.rs#L130-L166","documentation":"update_capsule found meta.json but its `source` field is absent, meaning the capsule was installed before source tracking existed. Without a recorded source the updater cannot know where to re-fetch updates from.","triggerScenarios":"Updating a capsule whose meta.json exists but predates the addition of the `source` field — i.e. capsules installed by an older astrid-cli that wrote partial metadata.","commonSituations":"Legacy capsule installations carried over across astrid-cli upgrades; meta.json hand-written or stripped of fields by tooling.","solutions":["Re-install the capsule manually so meta.json is written with the source field, then run the update again","If the original source is known, add a valid `source` entry to the capsule's meta.json","Recreate the capsule from its canonical source via capsule install"],"exampleFix":"// before: meta.json without source\n{\"name\": \"my-capsule\"}\n// after: reinstall to get\n{\"name\": \"my-capsule\", \"source\": \"git+https://example.com/my-capsule.git\"}","handlingStrategy":"validation","validationCode":"let meta = read_meta(&target_dir)?;\nif meta.source.is_none() {\n    eprintln!(\"Capsule '{}' predates source tracking; reinstalling is required.\", name);\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"match update_capsule(name).await {\n    Err(e) if e.to_string().contains(\"before source tracking\") => reinstall_manually(name)?,\n    other => other?,\n}","preventionTips":["Reinstall capsules after migrating from versions without source tracking","Keep meta.json's source field populated when editing metadata","Check `meta.source.is_some()` before scripting bulk updates"],"tags":["capsule","metadata-missing","legacy-install"],"backgroundTag":"missing-required-config-field","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}