{"record":{"id":"2f2e1b170f31b137","repo":"dagger/dagger","slug":"compat-workspace-is-required","errorCode":null,"errorMessage":"compat workspace is required","messagePattern":"compat workspace is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/workspace/migrate.go","lineNumber":158,"sourceCode":"\tWorkspaceConfigData      []byte\n\tMigratedModuleConfigData []byte\n\tMigratedModuleConfigPath string\n\tMigrationReportData      []byte\n}\n\n// PlanMigration computes the pure filesystem plan for migrating a compat\n// workspace into workspace format. workspaceRoot is the workspace boundary:\n// when the legacy config lives below it, the plan is \"hoisted\" — nested\n// dagger.toml files are never created, so the config's workspace fields\n// (toolchains) are installed into a dagger.toml at the workspace root with\n// their local sources rebased, while the module config still converts in\n// place at its own directory and the module itself is not installed.\n//\n// When the config has an SDK, its toolchains are also recorded as\n// dependencies of the migrated module config (see buildMigratedModuleConfig).\nfunc PlanMigration(compatWorkspace *CompatWorkspace, workspaceRoot string) (*MigrationPlan, error) {\n\tif compatWorkspace == nil || compatWorkspace.Config == nil {\n\t\treturn nil, fmt.Errorf(\"compat workspace is required\")\n\t}\n\tif compatWorkspace.ProjectRoot == \"\" {\n\t\treturn nil, fmt.Errorf(\"compat workspace project root is required\")\n\t}\n\tif compatWorkspace.ConfigPath == \"\" {\n\t\treturn nil, fmt.Errorf(\"compat workspace config path is required\")\n\t}\n\tif workspaceRoot == \"\" {\n\t\tworkspaceRoot = compatWorkspace.ProjectRoot\n\t}\n\n\tcfg := compatWorkspace.Config\n\tif !mustMigrateToWorkspaceConfig(cfg) {\n\t\treturn nil, fmt.Errorf(\"dagger.json does not require workspace config migration\")\n\t}\n\n\tmoduleRoot := compatWorkspace.ProjectRoot\n\thoistRel, err := filepath.Rel(filepath.Clean(workspaceRoot), filepath.Clean(moduleRoot))","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/workspace/migrate.go#L140-L176","documentation":"Input guard in PlanMigration: compatWorkspace (or its Config) is nil. The migration planner needs a parsed legacy dagger.json to plan from; a nil argument is programmer/caller error, not a config problem.","triggerScenarios":"Thrown at core/workspace/migrate.go:158 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Load and parse the legacy workspace before planning migration","Check the CompatWorkspace construction path for nil results"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}