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{}, permReqErr

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Invoke the tool through the standard coordinator path that injects the session ID
  2. Set the session ID in the context before executing (SetSessionInContext)
  3. 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

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


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/e58b4730c9b2bf1e. Report an issue: GitHub.