goreleaser/goreleaser · error
node: write sea-config.json: %w
Error message
node: write sea-config.json: %w
What it means
This error wraps the failure of os.WriteFile when GoReleaser tries to write the generated sea-config.json into the build directory during Node.js Single Executable Application (SEA) builds. The config file is what goreleaser later hands to `node --build-sea`, so if it cannot be written the SEA build cannot proceed. The wrapped %w preserves the underlying OS error (permissions, disk full, missing directory).
Source
Thrown at internal/builders/node/sea.go:50
return fmt.Errorf("node: abs build dir %q: %w", build.Dir, err)
}
cfg, err := buildSEAConfigJSON(
absBuildDir,
absMainPath,
targetNode,
output,
)
if err != nil {
return err
}
cfgBytes, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
if err := os.WriteFile(name, cfgBytes, 0o600); err != nil {
return fmt.Errorf("node: write sea-config.json: %w", err)
}
return nil
}
// buildSEAConfigJSON renders the sea-config.json contents goreleaser
// will hand to `node --build-sea`. Starts from the user's
// sea-config.json in buildDir (if any), then forces the
// goreleaser-owned fields and rewrites relative `assets` paths to be
// absolute relative to buildDir so they survive the move into the
// dist directory.
func buildSEAConfigJSON(buildDir, mainPath, targetNode, output string) (map[string]any, error) {
cfg, err := loadUserSEAConfig(buildDir)
if err != nil {
return nil, err
}
cfg["main"] = mainPath
cfg["output"] = outputView on GitHub (pinned to f5edd73956)
Solutions
- Check the underlying wrapped error (printed after 'node: write sea-config.json:') to see if it is ENOENT, EACCES, or ENOSPC and fix accordingly.
- Ensure the build directory (build.Dir) exists and is writable by the user running goreleaser before the build.
- Free disk space or raise quota if the error is no-space-left-on-device.
- Do not run the build from a read-only mount; adjust volume/container permissions.
Example fix
// before: building inside a root-owned directory // $ goreleaser build -> node: write sea-config.json: open ...: permission denied // after: make the workspace writable $ sudo chown -R $(whoami) ./dist $ goreleaser build
Defensive patterns
Strategy: validation
Validate before calling
const dir = './dist';
try {
await fs.access(dir, fs.constants.W_OK);
} catch {
throw new Error(`build dir ${dir} missing or not writable`);
} Prevention
- Ensure the build/dist directory exists and is writable before running goreleaser.
- Avoid read-only mounts for the build workspace in CI/containers.
- Monitor disk space; fail fast on low-space conditions.
- Run builds as a user that owns the workspace.
When it happens
Trigger: os.WriteFile(name, cfgBytes, 0o600) fails inside createSEAConfig (called from Build): e.g. the build directory does not exist, the process lacks write permission on it, or the disk is full.
Common situations: Building in a read-only CI workspace or one where a previous step deleted the dist/build directory; running goreleaser as a non-root user against a root-owned directory; a read-only container filesystem; disk quota exhaustion.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- node: read %s: %w
- %s is not a valid build target
- node: template tool: %w
- node: resolve node version: %w
- node: read package.json: %w
AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05).
Data as JSON: /api/errors/1892f434c3a8b6ef.
Report an issue: GitHub.