{"record":{"id":"aaaf93da502efafa","repo":"dagger/dagger","slug":"sdk-module-q-has-no-source","errorCode":null,"errorMessage":"SDK module %q has no source","messagePattern":"SDK module %q has no source","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/schema/workspace_sdk.go","lineNumber":243,"sourceCode":"\t\t}\n\t\tmatches = append(matches, moduleName)\n\t}\n\tsort.Strings(matches)\n\tswitch len(matches) {\n\tcase 0:\n\t\treturn \"\", workspace.ModuleEntry{}, \"\", fmt.Errorf(\"%q is not installed as an SDK in this workspace; run `dagger sdk install %s` first\", name, name)\n\tcase 1:\n\t\tentry := cfg.Modules[matches[0]]\n\t\treturn installedSDKSourceForModule(matches[0], entry)\n\tdefault:\n\t\treturn \"\", workspace.ModuleEntry{}, \"\", fmt.Errorf(\"SDK name %q is ambiguous: matches modules.%s.as-sdk; choose a unique as-sdk.name\", name, strings.Join(matches, \".as-sdk, modules.\"))\n\t}\n}\n\nfunc installedSDKSourceForModule(moduleName string, entry workspace.ModuleEntry) (string, workspace.ModuleEntry, string, error) {\n\tsource := moduleEntrySourceWithPin(entry)\n\tif source == \"\" {\n\t\treturn \"\", workspace.ModuleEntry{}, \"\", fmt.Errorf(\"SDK module %q has no source\", moduleName)\n\t}\n\treturn moduleName, entry, source, nil\n}\n\nfunc moduleEntrySourceWithPin(entry workspace.ModuleEntry) string {\n\treturn sourceWithPin(entry.Source, entry.Pin)\n}\n\nfunc resolvedModuleEntrySourceWithPin(configDir string, entry workspace.ModuleEntry) string {\n\treturn sourceWithPin(workspace.ResolveModuleEntrySource(configDir, entry.Source), entry.Pin)\n}\n\nfunc moduleEntrySourceWithPinRelativeTo(configDir, targetDir string, entry workspace.ModuleEntry) (string, error) {\n\tif !workspace.IsLocalRef(entry.Source, \"\") {\n\t\treturn moduleEntrySourceWithPin(entry), nil\n\t}\n\tsource := workspace.ResolveModuleEntrySource(configDir, entry.Source)\n\trel, err := filepath.Rel(targetDir, source)","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/schema/workspace_sdk.go#L225-L261","documentation":"Thrown by installedSDKSourceForModule in core/schema/workspace_sdk.go when a module entry matched as an SDK (by key or as-sdk name) has an empty effective source: moduleEntrySourceWithPin(entry) (source + optional @pin) returns \"\". An SDK install must point at a module source (local path or git ref with pin); without one Dagger cannot resolve where the SDK's module lives.","triggerScenarios":"installedSDKSource resolves a name to a workspace.ModuleEntry whose `source` field is empty or unset (and no pin can make it non-empty), e.g. a dagger.json modules entry that only contains an as-sdk block with no source path.","commonSituations":"Hand-editing dagger.json and adding an SDK/module entry with only a name but no `source`; tooling or a merge that dropped the source field; an entry scaffolded by a script that expected source to be filled in later; corrupt or truncated dagger.json.","solutions":["Add the missing `source` field to the module entry in dagger.json (local path or remote ref).","Re-run `dagger sdk install <name>` so Dagger rewrites the entry with a proper source and pin.","Restore the source value from version control (git diff/checkout dagger.json) if a merge or edit dropped it.","Remove the broken entry entirely if it is stale, then reinstall the SDK."],"exampleFix":"// before (dagger.json)\n{ \"modules\": { \"my-sdk\": { \"as-sdk\": { \"name\": \"my-sdk\" } } } }\n\n// after (dagger.json)\n{ \"modules\": { \"my-sdk\": { \"source\": \"modules/my-sdk\", \"pin\": \"abc123...\", \"as-sdk\": { \"name\": \"my-sdk\" } } } }","handlingStrategy":"validation","validationCode":"import \"encoding/json\"\n\nfunc sdkEntryHasSource(daggerJSONPath, sdkName string) error {\n  raw, err := os.ReadFile(daggerJSONPath)\n  if err != nil { return err }\n  var cfg struct {\n    Modules map[string]struct {\n      Source string `json:\"source\"`\n    } `json:\"modules\"`\n  }\n  if err := json.Unmarshal(raw, &cfg); err != nil { return err }\n  e, ok := cfg.Modules[sdkName]\n  if !ok { return fmt.Errorf(\"entry %q missing\", sdkName) }\n  if e.Source == \"\" { return fmt.Errorf(\"entry %q has empty source\", sdkName) }\n  return nil\n}","typeGuard":"func entryHasSource(e ModuleEntry) bool { return e.Source != \"\" }","tryCatchPattern":"mod, entry, src, err := installedSDKSourceForModule(moduleName, entry)\nif err != nil && strings.Contains(err.Error(), \"has no source\") {\n  return fmt.Errorf(\"reinstall %q to populate source: `dagger sdk install %s`\", moduleName, moduleName)\n}","preventionTips":["Prefer `dagger sdk install` over manual dagger.json edits so `source` (and `pin`) are always populated.","Validate dagger.json after merges: every modules entry must have a non-empty `source`.","Do not scaffold module entries with placeholder/empty source values; fill them before use.","Review git diffs of dagger.json for dropped `source` fields."],"tags":["dagger","workspace-config","module-source","config"],"backgroundTag":"missing-module-source","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}