{"record":{"id":"d6c097528a9d7663","repo":"dagger/dagger","slug":"sdk-target-runtime-is-empty","errorCode":null,"errorMessage":"SDK target runtime is empty","messagePattern":"SDK target runtime is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/schema/workspace_module_init.go","lineNumber":151,"sourceCode":"\tloadedSDK, err := s.loadWorkspaceSDK(ctx, ws, staged.ConfigDir, sdkRef)\n\tif err != nil {\n\t\treturn res, scope, err\n\t}\n\n\t// By default the SDK module is also the runtime. SDKs that split authoring\n\t// from execution advertise RuntimeTarget and provide the runtime ref.\n\tdefaultRuntimeRef, err := moduleEntrySourceWithPinRelativeTo(staged.ConfigDir, relPath, sdkEntry)\n\tif err != nil {\n\t\treturn res, scope, err\n\t}\n\truntimeRef := defaultRuntimeRef\n\tif target, ok := loadedSDK.AsRuntimeTarget(); ok {\n\t\truntimeRef, err = target.TargetRuntime(ctx)\n\t\tif err != nil {\n\t\t\treturn res, scope, fmt.Errorf(\"resolve SDK target runtime: %w\", err)\n\t\t}\n\t\tif runtimeRef == \"\" {\n\t\t\treturn res, scope, fmt.Errorf(\"SDK target runtime is empty\")\n\t\t}\n\t}\n\n\tif usingDefaultPath {\n\t\tcfg.Modules[args.Name] = workspace.ModuleEntry{Source: configPath}\n\t}\n\n\t// Render new dagger.toml bytes through the format-preserving editor.\n\tnewConfigBytes, err := workspace.UpdateConfigBytes(staged.Data, cfg)\n\tif err != nil {\n\t\treturn res, scope, fmt.Errorf(\"update workspace config: %w\", err)\n\t}\n\n\t// Generate the new module's config file (dagger-module.toml) ONLY. The\n\t// engine owns the module config; the SDK's initModule (merged in below)\n\t// owns every other file in the module directory — starter source, the\n\t// generated client, language scaffolding, etc. Emitting just the config\n\t// here keeps the engine and SDK changesets disjoint by construction, so","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/schema/workspace_module_init.go#L133-L169","documentation":"After resolving the SDK's target runtime reference, initModule verifies it is non-empty. If AsRuntimeTarget succeeded but TargetRuntime returned an empty string, the SDK declares itself a runtime target without providing a usable runtime reference — treated as a misconfigured SDK and rejected with this error.","triggerScenarios":"Calling workspace.initModule with an SDK whose TargetRuntime(ctx) implementation returns \"\" without error — typically a custom SDK with a stubbed or incorrectly implemented TargetRuntime.","commonSituations":"Custom SDKs under development where the runtime ref is derived from a config field left blank; SDK versions where the default runtime constant was removed; environment-dependent derivation producing an empty result.","solutions":["Fix the SDK's TargetRuntime implementation to return a valid runtime image reference.","Set whatever SDK config supplies the runtime ref (it is currently empty/blank).","Pin/upgrade to an SDK version with a working runtime declaration, or use a built-in SDK instead."],"exampleFix":"// before (custom SDK)\n// func (s *SDK) TargetRuntime(ctx) (string, error) { return s.cfg.Runtime, nil } // cfg.Runtime == \"\"\n// after\n// if s.cfg.Runtime == \"\" { return \"\", fmt.Errorf(\"runtime ref not configured\") }\n// return s.cfg.Runtime, nil","handlingStrategy":"validation","validationCode":"ref, err := sdk.TargetRuntime(ctx)\nif err != nil { return err }\nif ref == \"\" { return fmt.Errorf(\"SDK %q has no runtime ref configured\", sdkName) }","typeGuard":null,"tryCatchPattern":"res, err := ws.InitModule(ctx, args)\nif err != nil && strings.Contains(err.Error(), \"SDK target runtime is empty\") {\n\t// report that the SDK's runtime configuration is blank; fix the SDK config\n}","preventionTips":["Test custom SDKs' TargetRuntime returns a non-empty reference.","Fill in runtime config fields for custom SDKs before use.","Prefer built-in SDKs until a custom SDK declares a runtime."],"tags":["sdk","runtime","misconfiguration"],"backgroundTag":"sdk-runtime-empty","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"}