{"record":{"id":"2d43dacd504f2b59","repo":"vxcontrol/pentagi","slug":"failed-to-create-volume-w","errorCode":null,"errorMessage":"failed to create volume: %w","messagePattern":"failed to create volume: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/docker/client.go","lineNumber":331,"sourceCode":"\t\thostConfig = &container.HostConfig{}\n\t}\n\n\t// prevent containers from auto-starting after OS or docker daemon restart\n\t// because on startup they create docker.sock directory for DinD if it's enabled\n\thostConfig.RestartPolicy = container.RestartPolicy{\n\t\tName:              container.RestartPolicyOnFailure,\n\t\tMaximumRetryCount: 5,\n\t}\n\n\tif hostDir == \"\" {\n\t\tvolumeName, err := dc.client.VolumeCreate(ctx, client.VolumeCreateOptions{\n\t\t\tName:   fmt.Sprintf(\"%s%s\", containerName, WorkerVolumeNameSuffix),\n\t\t\tDriver: \"local\",\n\t\t\tLabels: dc.labels,\n\t\t})\n\t\tif err != nil {\n\t\t\tdefer updateContainerInfo(database.ContainerStatusFailed, \"\")\n\t\t\treturn database.Container{}, fmt.Errorf(\"failed to create volume: %w\", err)\n\t\t}\n\t\thostDir = volumeName.Volume.Name\n\t}\n\thostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf(\"%s:%s\", hostDir, WorkFolderPathInContainer))\n\n\tif dc.inside {\n\t\t// The socket is empty when DOCKER_INSIDE_HOST designates a daemon endpoint\n\t\t// instead; binding \"\" would produce a malformed mount spec.\n\t\tif dc.socket != \"\" {\n\t\t\thostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf(\"%s:%s\", dc.socket, defaultDockerSocketPath))\n\t\t}\n\n\t\t// Point the sandbox's Docker CLI at the designated daemon.\n\t\tconfig.Env = append(config.Env, dc.insideEnv...)\n\n\t\t// TLS material is mounted read-only at the same path on both sides so the\n\t\t// injected DOCKER_CERT_PATH resolves unchanged inside the container.\n\t\tif dc.insideCertPath != \"\" {","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/docker/client.go#L313-L349","documentation":"When the client was constructed without a host directory (hostDir == \"\"), RunContainer creates a named Docker volume named <containerName>-data to back the /work mount instead of a bind mount. If VolumeCreate fails the container is marked Failed and the error \"failed to create volume: %w\" is returned. This wraps a daemon error — inspect the cause (named volume name conflicts, driver errors, storage limits).","triggerScenarios":"dc.client.VolumeCreate fails: a volume with the same name already exists but is in use with incompatible labels, the 'local' volume driver errors (bad volume options, storage backend full), daemon read-only in an insecure sandbox, or the volume name contains characters rejected by the daemon.","commonSituations":"Container names reused across runs (e.g. retried flow producing the same <name>-data volume) combined with label/tenant changes; disk full on the Docker volume host; running with a restricted daemon (Docker rootless quota exceeded); name containing invalid characters from an injected tool name.","solutions":["Inspect the wrapped cause; check for an existing conflicting volume: docker volume ls / docker volume inspect <name>-data, remove it if stale (docker volume rm).","Free disk space on the Docker storage host (docker system df, docker volume prune).","Ensure container names are unique per flow/run so the <name>-data volume name does not collide with a live volume.","If labels/tenants changed, delete the old volume created with the previous labels before rerunning.","Check daemon logs (journalctl -u docker) for volume driver errors."],"exampleFix":"# before: retry loop reuses same container name → same volume name\nname := fmt.Sprintf(\"tool-%s\", toolName)             # collides with existing volume tool-x-data\n# after\nname := fmt.Sprintf(\"tool-%s-flow-%d\", toolName, flowID)  # unique volume per flow","handlingStrategy":"try-catch","validationCode":"volName := containerName + \"-data\"\nvols, err := cli.VolumeList(ctx, client.VolumeListOptions{})\nif err == nil {\n    for _, v := range vols.Volumes {\n        if v.Name == volName {\n            // exists: decide to reuse or remove before VolumeCreate\n            _ = cli.VolumeRemove(ctx, volName, false)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"_, err := dc.RunContainer(ctx, name, ctype, flowID, cfg, hostCfg)\nvar derr *client.VolumeCreateError // or match on message\nif err != nil && strings.Contains(err.Error(), \"failed to create volume\") {\n    _ = cli.VolumeRemove(context.Background(), name+\"-data\", true)\n    return retryOnce() // recreate volume with fresh state\n}","preventionTips":["Generate unique container names per flow/run so derived volume names never collide.","Schedule docker volume prune during maintenance windows.","Monitor disk usage on the Docker storage host.","Keep container names within Docker's naming charset (avoid odd characters from tool inputs).","Check daemon volume driver health when running on non-default storage backends."],"tags":["docker","volume","storage"],"backgroundTag":"docker-volume-create-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}