Tencent/WeKnora · error

sandbox: create workspace directory: %w

Error message

sandbox: create workspace directory: %w

What it means

WriteSessionWorkspaceFile (for model-authored files) calls MakeDir on the parent of the cleaned target path after ensuring standard workspace dirs; failure is wrapped as "sandbox: create workspace directory". The workspace dirs under SessionOutputRoot are best-effort (errors ignored), so this error means the specific parent directory of the target file could not be created.

Source

Thrown at internal/sandbox/session_manager.go:551

	ctx context.Context, sessionID, filePath string, content []byte,
) error {
	if err := m.requireRemoteBackend(); err != nil {
		return err
	}
	if strings.TrimSpace(sessionID) == "" {
		return errors.New("sandbox: session ID required for workspace write")
	}
	clean, err := cleanSessionWorkspaceWritePath(filePath)
	if err != nil {
		return err
	}
	handle, err := m.resolveSession(ctx, sessionID)
	if err != nil {
		return err
	}
	m.ensureSessionWorkspaceDirs(ctx, handle, SessionOutputRoot)
	if err := ignoreExistingDir(m.client.MakeDir(ctx, handle, path.Dir(clean))); err != nil {
		return fmt.Errorf("sandbox: create workspace directory: %w", err)
	}
	if err := m.client.WriteFile(ctx, handle, clean, content); err != nil {
		return fmt.Errorf("sandbox: write session file %s: %w", clean, err)
	}
	return nil
}

// RemoveSessionInputPath deletes a staged attachment. It is a no-op when the
// session has no live sandbox and never provisions one.
func (m *SessionBoundManager) RemoveSessionInputPath(
	ctx context.Context, sessionID, targetPath string,
) error {
	if err := m.requireRemoteBackend(); err != nil {
		return err
	}
	clean, err := cleanSessionInputPath(targetPath)
	if err != nil {
		return err

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Inspect the wrapped error to identify permission vs. path problems.
  2. Sanitize/validate model-authored paths before writing (clean, restrict to workspace root).
  3. Verify the sandbox is alive; re-resolve the session and retry.
  4. Check provider disk quotas.

Example fix

// before
p := modelOutput.Name() // may contain spaces/odd chars
err := mgr.WriteSessionWorkspaceFile(ctx, sessionID, p, data)
// after
p := path.Join("/workspace", path.Clean(sanitizeName(modelOutput.Name())))
err := mgr.WriteSessionWorkspaceFile(ctx, sessionID, p, data)
Defensive patterns

Strategy: validation

Validate before calling

// sanitize model-authored paths before writing
func sanitizeWorkspacePath(name string) string {
    name = path.Clean("/" + name) // anchor to root, drop ..
    name = strings.Map(func(r rune) rune {
        if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '.' || r == '-' || r == '_' || r == '/' {
            return r
        }
        return '_'
    }, name)
    return path.Join("/workspace", name)
}

Try / catch

if err := mgr.WriteSessionWorkspaceFile(ctx, sessionID, p, data); err != nil {
    if strings.Contains(err.Error(), "create workspace directory") {
        return fmt.Errorf("workspace path %q rejected by sandbox: %w", p, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling WriteSessionWorkspaceFile when MakeDir(path.Dir(clean)) fails — permission denied, invalid nested path, sandbox terminated mid-call, or provider API error.

Common situations: Model-generated paths containing illegal characters or escaping the workspace root, sandbox image with read-only workspace, quota exceeded, or a stale sandbox handle after expiry.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/15d94e77b677eae8. Report an issue: GitHub.