charmbracelet/crush · error

session ID is required for executing shell command

Error message

session ID is required for executing shell command

What it means

The bash tool resolves the caller's session ID from the request context via GetSessionFromContext; if absent it refuses to execute the command, because the session ID is mandatory for the permission request (CreatePermissionRequest.SessionID) and for tracking the shell job. This is a guard against executing commands outside an agent session.

Source

Thrown at internal/agent/tools/bash.go:225

			execWorkingDir := cmp.Or(params.WorkingDir, workingDir)

			isSafeReadOnly := false
			cmdLower := strings.ToLower(params.Command)

			if !containsCommandChaining(params.Command) {
				for _, safe := range safeCommands {
					if strings.HasPrefix(cmdLower, safe) {
						if len(cmdLower) == len(safe) || cmdLower[len(safe)] == ' ' || cmdLower[len(safe)] == '-' {
							isSafeReadOnly = true
							break
						}
					}
				}
			}

			sessionID := GetSessionFromContext(ctx)
			if sessionID == "" {
				return fantasy.ToolResponse{}, fmt.Errorf("session ID is required for executing shell command")
			}
			if !isSafeReadOnly {
				p, err := permissions.Request(
					ctx,
					permission.CreatePermissionRequest{
						SessionID:   sessionID,
						Path:        execWorkingDir,
						ToolCallID:  call.ID,
						ToolName:    BashToolName,
						Action:      "execute",
						Description: fmt.Sprintf("Execute command: %s", params.Command),
						Params:      BashPermissionsParams(params),
					},
				)
				if err != nil {
					return fantasy.ToolResponse{}, err
				}
				if !p {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Wrap the call context with the session ID the agent sets (use the same SetSessionInContext/GetSessionFromContext helper the agent uses before invoking the tool)
  2. If driving tools yourself, replicate internal/agent's per-request context setup so GetSessionFromContext returns a non-empty ID
  3. In tests, inject a fake session ID into ctx before calling the tool handler

Example fix

// before
resp, err := tool.Run(ctx, params)
// after
ctx = agent.SetSessionInContext(ctx, "my-session-id")
resp, err := tool.Run(ctx, params)
Defensive patterns

Strategy: validation

Validate before calling

if agent.GetSessionFromContext(ctx) == "" {
    return errors.New("call the bash tool within a session-scoped context")
}

Prevention

When it happens

Trigger: Invoking the bash tool handler with a context that was never populated by SetSessionInContext — e.g. calling the fantasy tool function directly in tests or custom code without session middleware, or running the tool in a path that bypasses the agent's context setup.

Common situations: Unit/integration tests constructing the tool and calling it with context.Background(); embedding the tool into a custom runner that forgets to attach the session ID; third-party integrations calling tool.Run without the app's session plumbing.

Related errors


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