pulumi/pulumi · error
could not import stack, failed to marshal stack state: %w
Error message
could not import stack, failed to marshal stack state: %w
What it means
ImportStack marshals the provided apitype.UntypedDeployment to JSON before writing it to the temp file. This error is returned if json.Marshal fails, which for UntypedDeployment practically means the struct contains values that cannot be serialized.
Source
Thrown at sdk/go/auto/local_workspace.go:827
fmt.Errorf("failed to export stack, unable to unmarshall stack state: %w", err), stdout, stderr, errCode,
)
}
return state, nil
}
// ImportStack imports the specified deployment state into a pre-existing stack.
// This can be combined with ExportStack to edit a stack's state (such as recovery from failed deployments).
func (l *LocalWorkspace) ImportStack(ctx context.Context, stackName string, state apitype.UntypedDeployment) error {
f, err := os.CreateTemp(os.TempDir(), "")
if err != nil {
return fmt.Errorf("could not import stack. failed to allocate temp file: %w", err)
}
defer func() { contract.IgnoreError(os.Remove(f.Name())) }()
bytes, err := json.Marshal(state)
if err != nil {
return fmt.Errorf("could not import stack, failed to marshal stack state: %w", err)
}
_, err = f.Write(bytes)
if err != nil {
return fmt.Errorf("could not import stack. failed to write out stack intermediate: %w", err)
}
stdout, stderr, errCode, err := l.runPulumiCmdSync(ctx, "stack", "import", "--file", f.Name(), "--stack", stackName)
if err != nil {
return newAutoError(fmt.Errorf("could not import stack: %w", err), stdout, stderr, errCode)
}
return nil
}
// StackOutputs gets the current set of Stack outputs from the last Stack.Up().
func (l *LocalWorkspace) StackOutputs(ctx context.Context, stackName string) (OutputMap, error) {
// standard outputsView on GitHub (pinned to 793f7b2e16)
Solutions
- Obtain state via ExportStack instead of hand-building apitype.UntypedDeployment
- Validate the Deployment JSON yourself with json.Valid / a test Marshal before calling ImportStack
- Check for invalid UTF-8 or control characters if the state was produced by another tool
- Log the failing field by marshaling components separately to isolate the bad value
Example fix
// before
err := ws.ImportStack(ctx, "dev", handEditedState)
// after - validate first
if !json.Valid(handEditedState.Deployment) {
return errors.New("deployment bytes are not valid JSON")
}
err := ws.ImportStack(ctx, "dev", handEditedState) Defensive patterns
Strategy: validation
Validate before calling
raw, err := json.Marshal(state)
if err != nil { return fmt.Errorf("state not marshalable: %w", err) }
if !json.Valid(state.Deployment) { return errors.New("deployment payload is not valid JSON") } Type guard
func validDeployment(state apitype.UntypedDeployment) bool {
return json.Valid(state.Deployment) && state.Version != 0
} Try / catch
if err := ws.ImportStack(ctx, stackName, state); err != nil {
if strings.Contains(err.Error(), "failed to marshal stack state") {
return fmt.Errorf("state produced outside ExportStack is corrupt: %w", err)
}
return err
} Prevention
- Only feed ImportStack state obtained from ExportStack
- Run json.Valid on deployment bytes before import
- Avoid manual edits to exported state or validate after edits
- Marshal state once in a test to catch non-serializable fields early
When it happens
Trigger: Calling ImportStack with a state value that was hand-constructed or round-tripped through something producing non-marshalable content (e.g. invalid UTF-8 in deployment bytes) rather than coming from ExportStack.
Common situations: Custom tooling editing exported state and corrupting it; loading state from a source that produces invalid JSON data; unmarshal-then-marshal round trips losing valid types.
Related errors
- could not refresh config: %w
- could not export stack: %w
- failed to export stack, unable to unmarshall stack state: %w
- failed to normalize URN references: %w
- marshaling environment overrides: %w
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/d06a510b535b75d3.
Report an issue: GitHub.