{"record":{"id":"42bc0109861c3906","repo":"Tencent/WeKnora","slug":"cannot-run-workspace-script-q-for-skill-q-no-in","errorCode":null,"errorMessage":"cannot run workspace script %q for skill %q: no installed skill directory","messagePattern":"cannot run workspace script %q for skill %q: no installed skill directory","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/skills/manager.go","lineNumber":510,"sourceCode":"\tsource SkillSource,\n\tskillName, workspacePath, basePath string,\n\targs []string,\n\tstdin string,\n\tenv map[string]string,\n\tsessionID string,\n) (*sandbox.ExecuteConfig, error) {\n\tif !IsScript(workspacePath) {\n\t\treturn nil, fmt.Errorf(\"file is not an executable script: %s\", workspacePath)\n\t}\n\tif _, installed := source.(imageSkillSource); !installed {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"script_path %q is a session workspace file; this skill is not installed in the sandbox image, so execute_skill_script cannot attach its environment. Run it with shell_exec, or pass a skill-relative path such as scripts/foo.py\",\n\t\t\tworkspacePath,\n\t\t)\n\t}\n\tskillDir, ok := sandbox.ValidatedImageSkillDir(basePath)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"cannot run workspace script %q for skill %q: no installed skill directory\", workspacePath, skillName)\n\t}\n\tenv[skillDirEnvVar] = skillDir\n\treturn &sandbox.ExecuteConfig{\n\t\tRemoteScriptPath: workspacePath,\n\t\tSkillDir:         skillDir,\n\t\tArgs:             args,\n\t\tStdin:            stdin,\n\t\tEnv:              env,\n\t\tSessionID:        sessionID,\n\t}, nil\n}\n\n// sessionFileStoreFromManager returns the sandbox manager's effective\n// session filesystem capability, or nil when the backend cannot expose one.\n// Isolated in a helper so callers stay free of provider-specific branches.\nfunc sessionFileStoreFromManager(mgr sandbox.Manager) sandbox.SessionFileStore {\n\tprovider, ok := mgr.(sandbox.SessionCapabilityProvider)\n\tif !ok || provider == nil {","sourceCodeStart":492,"sourceCodeEnd":528,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/skills/manager.go#L492-L528","documentation":"For a workspace script run against an image-installed skill, the skill's base path must pass sandbox.ValidatedImageSkillDir (i.e. resolve to a real, validated installed skill directory in the image). An empty or invalid basePath means there is no installed directory to attach, so the run is refused.","triggerScenarios":"Manager.ExecuteScript with a /workspace script path where the skill reports itself as image-installed but basePath from GetSkillBasePath is empty or fails validation — e.g. corrupt/missing install record, image without the skill directory despite metadata claiming it.","commonSituations":"Image build skipped or pruned the skill directory while skill metadata remained; path validation failing (empty dir, path traversal); stale metadata after image rebuild.","solutions":["Rebuild/reinstall the sandbox image so the skill directory actually exists at the expected path","Verify GetSkillBasePath returns a non-empty valid directory for the skill","Check sandbox.ValidatedImageSkillDir requirements (path shape/existence) against the configured basePath","Fall back to shell_exec for the workspace script while the install is broken"],"exampleFix":"// before\nbasePath, _ := source.GetSkillBasePath(skillName) // returns \"\" -> error later\n// after\nif dir, ok := mgr.SandboxSkillDir(skillName); !ok || dir == \"\" {\n    return fmt.Errorf(\"skill %s not installed in image; use shell_exec\", skillName)\n}","handlingStrategy":"try-catch","validationCode":"dir, ok := mgr.SandboxSkillDir(skillName)\nif !ok || dir == \"\" {\n    return fmt.Errorf(\"skill %s has no installed image dir\", skillName)\n}","typeGuard":"func hasValidImageDir(m *skills.Manager, name string) bool {\n    dir, ok := m.SandboxSkillDir(name)\n    return ok && strings.TrimSpace(dir) != \"\"\n}","tryCatchPattern":"_, err := mgr.ExecuteScript(ctx, skill, wsPath, args, stdin)\nif err != nil && strings.Contains(err.Error(), \"no installed skill directory\") {\n    // reinstall image or fall back to shell_exec\n}\nreturn err","preventionTips":["Verify image builds actually copy skill directories","Check basePath validity (ValidatedImageSkillDir) during install verification","Fail fast at image start if expected skill dirs are missing","Keep skill metadata and image contents in sync on rebuilds"],"tags":["go","image","skill-dir","validation"],"backgroundTag":"skill-not-installed-in-image","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}