charmbracelet/crush · error
session ID is required for accessing files outside working d
Error message
session ID is required for accessing files outside working directory
What it means
The view tool requires a session ID before it can run its permission flow for files outside the working directory. The session ID is fetched unconditionally (even for in-workdir files), so an empty context value fails the call regardless of the target path. Like error 200, this indicates the tool was invoked without the agent's session-scoped context.
Source
Thrown at internal/agent/tools/view.go:132
// Check if file is outside working directory and request permission if needed
absWorkingDir, err := filepath.Abs(workingDir)
if err != nil {
return fantasy.ToolResponse{}, fmt.Errorf("error resolving working directory: %w", err)
}
absFilePath, err := filepath.Abs(filePath)
if err != nil {
return fantasy.ToolResponse{}, fmt.Errorf("error resolving file path: %w", err)
}
relPath, err := filepath.Rel(absWorkingDir, absFilePath)
isOutsideWorkDir := err != nil || strings.HasPrefix(relPath, "..")
isSkillFile := isInSkillsPath(absFilePath, skillsPaths)
sessionID := GetSessionFromContext(ctx)
if sessionID == "" {
return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for accessing files outside working directory")
}
// Request permission for files outside working directory, unless it's a skill file.
if isOutsideWorkDir && !isSkillFile {
granted, permReqErr := permissions.Request(
ctx,
permission.CreatePermissionRequest{
SessionID: sessionID,
Path: absFilePath,
ToolCallID: call.ID,
ToolName: ViewToolName,
Action: "read",
Description: fmt.Sprintf("Read file outside working directory: %s", absFilePath),
Params: ViewPermissionsParams(params),
},
)
if permReqErr != nil {
return fantasy.ToolResponse{}, permReqErrView on GitHub (pinned to 7944b8e522)
Solutions
- Invoke the tool through the standard coordinator path that injects the session ID
- Set the session ID in the context before executing (SetSessionInContext)
- Report as a bug if it happens in normal Crush usage
Example fix
// before tool.Execute(ctx, call) // no session in ctx // after tool.Execute(tools.SetSessionInContext(ctx, sessionID), call)
Defensive patterns
Strategy: validation
Validate before calling
if tools.GetSessionFromContext(ctx) == "" {
return errors.New("view tool requires a session ID in context")
} Type guard
func hasSession(ctx context.Context) bool {
return tools.GetSessionFromContext(ctx) != ""
} Try / catch
if err != nil && strings.Contains(err.Error(), "session ID is required") {
return tool.Execute(tools.SetSessionInContext(ctx, sessionID), call)
} Prevention
- Route tool execution through the coordinator which injects the session ID
- In custom runners, set the session context value before every tool call
- Cover context wiring in integration tests
When it happens
Trigger: Invoking the view tool directly (tests, custom runners) without SetSessionInContext; a custom agent path that builds tool contexts without the session ID.
Common situations: Custom agent integrations; test harnesses calling the tool function directly; regressions after refactoring context plumbing.
Related errors
- session ID is required for executing shell command
- session ID is required for downloading files
- session ID is required for creating a new file
- %s
- session ID is required for creating a new file
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/e58b4730c9b2bf1e.
Report an issue: GitHub.