{"record":{"id":"614ac2e12c471120","repo":"floci-io/floci","slug":"could-not-create-build-working-directory-cont","errorCode":null,"errorMessage":"Could not create build working directory  \" + containerSrcDir + \":  \" + workDirResult.errorMessage()","messagePattern":"Could not create build working directory  \" \\+ containerSrcDir \\+ \":  \" \\+ workDirResult\\.errorMessage\\(\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"src/main/java/io/github/hectorvent/floci/services/codebuild/CodeBuildRunner.java","lineNumber":244,"sourceCode":"            containerId = info.containerId();\n            runningContainers.put(buildId, containerId);\n\n            logHandle = logStreamer.attach(containerId, logGroup, logStream, region, \"codebuild:\" + buildId);\n\n            String containerSrcDir = \"/codebuild/output/src/src\";\n            int timeoutMinutes = build.getTimeoutInMinutes() != null ? build.getTimeoutInMinutes() : 60;\n            boolean buildFailed = false;\n\n            // createAndStart returns as soon as the container's entrypoint process is\n            // running, which can be before any startup command would finish. Create the\n            // working directory with an explicit, awaited exec (run from \"/\", which always\n            // exists) so the source copy, the phase execs that chdir into it, and the final\n            // artifact copy can never race against container startup.\n            PhaseResult workDirResult = runPhase(containerId, \"/\", envList,\n                    List.of(\"mkdir -p \" + containerSrcDir), timeoutMinutes, stopFlag);\n            if (workDirResult.stopped()) { finishStopped(build); return; }\n            if (workDirResult.failed()) {\n                throw new IllegalStateException(\"Could not create build working directory \"\n                        + containerSrcDir + \": \" + workDirResult.errorMessage());\n            }\n\n            // Copy downloaded source files into the container (no-op for NO_SOURCE builds)\n            copySourceToContainer(containerId, workspace, containerSrcDir);\n\n            // INSTALL\n            if (stopFlag.get()) { finishStopped(build); return; }\n            beginPhase(build, \"INSTALL\");\n            build.setCurrentPhase(\"INSTALL\");\n            PhaseResult installResult = runPhase(containerId, containerSrcDir, envList,\n                    buildspec.installCommands(), timeoutMinutes, stopFlag);\n            if (installResult.stopped()) { finishStopped(build); return; }\n            if (installResult.failed()) {\n                completePhaseWithError(build, \"INSTALL\", \"FAILED\", installResult.errorMessage());\n                buildFailed = true;\n            } else {\n                completePhase(build, \"INSTALL\", \"SUCCEEDED\");","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/codebuild/CodeBuildRunner.java#L226-L262","documentation":"An IllegalStateException thrown by CodeBuildRunner when the awaited 'mkdir -p <containerSrcDir>' exec inside the just-started build container fails. The mkdir runs from '/' with the build's env before any source copy or phase exec so those cannot race container startup; if it fails the container is unusable and the build cannot proceed. The message embeds the exec's stderr errorMessage().","triggerScenarios":"The Docker container exited or crashed immediately after start (bad entrypoint, missing image); the image lacks mkdir or a POSIX shell so the exec fails; the mounted volume or workspace path is invalid inside the container; Docker daemon errors (disk full, IO) cause the exec to return non-zero.","commonSituations":"Using a custom environment image (e.g. minimal distroless or scratch) that has no mkdir binary; image pull silently produced a wrong/broken tag; Docker host out of disk or overlayfs errors; container runtime (podman/rootless) restrictions on exec.","solutions":["Inspect the embedded errorMessage() and docker logs for the container to find why mkdir failed","Use an image with a standard shell and coreutils (e.g. aws/codebuild/standard:7.0 or ubuntu-based) as the build environment image","Verify Docker disk space and daemon health (docker system df, docker run --rm <image> mkdir -p /tmp/x)","Check that the workspace/source path configuration does not collide with an existing read-only path in the image"],"exampleFix":"# before\nenvironment:\n  image: scratch-like/no-shell\n\n# after\nenvironment:\n  image: aws/codebuild/standard:7.0","handlingStrategy":"retry","validationCode":"# Pre-flight the image can run mkdir\ndocker run --rm \"$IMAGE\" sh -c 'mkdir -p /codebuild/tmp' || echo \"image lacks shell/mkdir - build will fail\"","typeGuard":null,"tryCatchPattern":"// Container-level failures can be transient (daemon/disk) - retry only after fixing the image\ncatch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"working directory\")) {\n        // inspect docker logs, fix image or daemon, then retry the build\n        markBuildForRetryAfterImageFix(buildId);\n    } else throw e;\n}","preventionTips":["Use shell-capable images (aws/codebuild/standard:7.0) for builds","Monitor Docker disk space on the Floci host","Test custom images with a trivial mkdir exec before wiring them into projects"],"tags":["codebuild","docker","container","runner"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}