Skip to content

[Bug]: Sandbox resume ignores updated WorkspaceSpec configuration #1926

Description

@Buktal

Describe the bug

When an application modifies WORKSPACE_PROJECTION_ROOTS in SandboxFilesystemSpec (e.g., adding .skills-cache to the projection list), the change is ignored for existing sandboxes resumed from Redis. The sandbox continues using the old WorkspaceSpec persisted in SandboxState, even though the application layer has provided an updated configuration.

To Reproduce

  1. Initial deployment — Application configures projection roots:

    private static final List<String> WORKSPACE_PROJECTION_ROOTS = 
        List.of("AGENTS.md", "skills", "subagents", "knowledge");
    
    new KubernetesFilesystemSpec()
        .workspaceProjectionRoots(WORKSPACE_PROJECTION_ROOTS);

    First run creates sandbox, SandboxState.workspaceSpec (containing the projection config) is persisted to Redis.

  2. Configuration update — Add .skills-cache to projection roots:

    private static final List<String> WORKSPACE_PROJECTION_ROOTS = 
        List.of("AGENTS.md", "skills", "subagents", "knowledge", ".skills-cache");

    Redeploy the application.

  3. Observe the issue — The .skills-cache directory exists on the host but is NOT projected into the sandbox.

  4. Workaround — Delete the Redis cache (or manually call stateStore.delete(scopeKey)). The sandbox is recreated with the new configuration, and .skills-cache appears.

Expected behavior

When the application layer updates WORKSPACE_PROJECTION_ROOTS, the next sandbox resume should apply the updated configuration, not the stale config persisted in Redis.

Root cause

SandboxManager.acquire() (L101-108) deserializes SandboxState from Redis and directly passes it to client.resume(state). The WorkspaceSpec inside state was captured during the first create() call and is never updated.

Later, AbstractBaseSandbox.start() (L71) uses state.getWorkspaceSpec() — the stale spec from Redis — instead of the fresh spec from SandboxContext.

// SandboxManager.java L106-107
SandboxState state = client.deserializeState(stateJson.get());
Sandbox sandbox = client.resume(state);  // ← state.workspaceSpec is stale

// AbstractBaseSandbox.java L71
WorkspaceSpec spec = state.getWorkspaceSpec();  // ← uses stale spec

Proposed fix

After deserializing SandboxState, overwrite state.workspaceSpec with the current sandboxContext.workspaceSpec:

// SandboxManager.java L106-109
SandboxState state = client.deserializeState(stateJson.get());
if (sandboxContext.getWorkspaceSpec() != null) {
    state.setWorkspaceSpec(sandboxContext.getWorkspaceSpec().copy());
}
Sandbox sandbox = client.resume(state);

This ensures resumed sandboxes respect updated application configuration.

Environment

  • AgentScope-Java Version: 2.0.0-SNAPSHOT (commit ddad83a)
  • Java Version: 17
  • OS: Windows 11

Additional context

This issue affects all WorkspaceSpec configuration changes:

  • Workspace projection roots (the reported case)
  • Environment variables
  • Workspace entries

The current design prioritizes state persistence over configuration updates, which is counter-intuitive for application developers who expect configuration changes to take effect after redeployment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions