diff --git a/scripts/nemoclaw-start.sh b/scripts/nemoclaw-start.sh index 4c68e2925..f5c39ed25 100755 --- a/scripts/nemoclaw-start.sh +++ b/scripts/nemoclaw-start.sh @@ -298,6 +298,45 @@ if [ "$(id -u)" -ne 0 ]; then echo "[SECURITY] Config integrity check failed — refusing to start (non-root mode)" exit 1 fi + + # Ensure writable state directories exist and are owned by the current user. + # The Docker build (Dockerfile) sets this up correctly, but the native curl + # installer may create these directories as root, causing EACCES when openclaw + # tries to write device-auth.json or other state files. Ref: #692 + fix_openclaw_data_ownership() { + local data_dir="${HOME}/.openclaw-data" + local openclaw_dir="${HOME}/.openclaw" + [ -d "$data_dir" ] || return 0 + local subdirs="agents/main/agent extensions workspace skills hooks identity devices canvas cron" + for sub in $subdirs; do + mkdir -p "${data_dir}/${sub}" 2>/dev/null || true + done + if find "$data_dir" ! -uid "$(id -u)" -print -quit 2>/dev/null | grep -q .; then + if chown -R "$(id -u):$(id -g)" "$data_dir" 2>/dev/null; then + echo "[setup] fixed ownership on ${data_dir}" + else + echo "[setup] could not fix ownership on ${data_dir}; writes may fail" >&2 + fi + fi + if [ -d "${data_dir}/identity" ]; then + mkdir -p "${openclaw_dir}" 2>/dev/null || true + if [ -L "${openclaw_dir}/identity" ]; then + local current_target expected_target + current_target="$(readlink -f "${openclaw_dir}/identity" 2>/dev/null || true)" + expected_target="$(readlink -f "${data_dir}/identity" 2>/dev/null || true)" + if [ "$current_target" != "$expected_target" ]; then + ln -snf "${data_dir}/identity" "${openclaw_dir}/identity" 2>/dev/null || true + echo "[setup] repaired identity symlink" + fi + elif [ ! -e "${openclaw_dir}/identity" ]; then + ln -snf "${data_dir}/identity" "${openclaw_dir}/identity" 2>/dev/null || true + echo "[setup] created identity symlink" + else + echo "[setup] ${openclaw_dir}/identity exists and is not a symlink; leaving as-is" >&2 + fi + fi + } + fix_openclaw_data_ownership write_auth_profile if [ ${#NEMOCLAW_CMD[@]} -gt 0 ]; then