April 15, 2026

[DevClaw crea silenciosamente una bifurcación del estado del registro de proyectos] - DevClaw Silently Forks Project Registry State by Creating Empty devclaw/projects.json

La estructura del workspace crea un registro canónico vacío sin detectar el estado heredado, lo que provoca que los proyectos parezcan faltantes después del reinicio.

🔍 Síntomas

Comportamiento observable

Cuando el andamiaje del espacio de trabajo de DevClaw encuentra un registro canónico faltante, crea uno vacío sin detectar el estado heredado preexistente:


# Canonical registry path
$ cat ~/.openclaw/workspace/devclaw/projects.json
{
  "projects": {}
}

El registro está vacío a pesar de que los proyectos se registraron en sesiones anteriores.

Manifestaciones posteriores

Los usuarios encuentran los siguientes fallos operativos:

  • Proyectos faltantes después del reinicio: Los proyectos registrados en sesiones anteriores ya no aparecen en `devclaw projects list`
  • Fallos de enrutamiento de canales: El enrutamiento de tareas falla con errores de Proyecto no encontrado para canales previamente registrados
  • Anomalías de comportamiento de herramientas: Las herramientas de proyecto/tarea devuelven resultados vacíos o errores de "ningún proyecto registrado"
  • Bifurcación silenciosa del estado: No se emite ninguna advertencia o error durante el inicio que indique que el estado heredado fue ignorado

Salida del comando de diagnóstico


$ devclaw projects list
[]
$ devclaw status
Project Registry: EMPTY
Last Updated: (timestamp of empty file creation)

$ ls -la ~/.openclaw/workspace/devclaw/
total 8
drwxr-xr-x  2 sai sai  4096 Jan 20 10:30 devclaw/
-rw-r--r--  1 sai sai     0 Jan 20 10:30 projects.json

# Legacy registry still exists unexamined
$ ls -la ~/.openclaw/workspace/
total 8
-rw-r--r--  1 sai sai 2048 Jan 19 14:22 projects.json  # Legacy state ignored
drwxr-xr-x  2 sai sai  4096 Jan 20 10:30 devclaw/

🧠 Causa raíz

Contexto arquitectónico

DevClaw mantiene un registro de proyectos como su estado de plano de control. El registro rastrea todos los proyectos registrados, sus metadatos e información de enrutamiento de canales. Este estado se persiste en disco en una ruta canónica.

Secuencia de fallos

El fallo crítico ocurre durante la inicialización del espacio de trabajo en la siguiente secuencia:

  1. Andamiaje del espacio de trabajo activado: En el primer inicio o cuando falta la estructura de directorio canónica, DevClaw ejecuta la lógica de andamiaje del espacio de trabajo
  2. Detección de registro canónico faltante: El andamiaje verifica la existencia de ~/.openclaw/workspace/devclaw/projects.json
  3. La ausencia implica estado nuevo: El andamiaje interpreta "archivo faltante" como "espacio de trabajo nuevo" sin consultar ubicaciones heredadas
  4. Registro vacío creado: Se escribe un { "projects": {} } vacío en la ruta canónica
  5. Estado heredado huérfano: Los registros preexistentes en rutas heredadas no se detectan ni migran

Análisis de flujo de código


// Pseudocode representation of current scaffolding behavior
function initializeWorkspace():
    canonicalRegistry = resolvePath("~/.openclaw/workspace/devclaw/projects.json")
    
    if not fileExists(canonicalRegistry):
        # BUG: Missing check for legacy registry locations
        createDirectoryStructure()
        writeEmptyRegistry(canonicalRegistry)  # Silent fork occurs here
        return
    
    # Only reached if canonical exists
    loadRegistry(canonicalRegistry)

Ubicaciones de registros heredados

Históricamente, DevClaw soportó múltiples rutas de almacenamiento de registros:

  • ~/.openclaw/workspace/projects.json
  • ~/.openclaw/workspace/projects/projects.json
  • ~/.openclaw/projects.json

El andamiaje actual no consulta estas rutas antes de crear un registro canónico nuevo.

Por qué esto es peligroso

El fallo es silencioso porque:

  • El código de salida es 0 (éxito)
  • No hay salida de consola indicando la creación del registro
  • No hay verificación de integridad comparando el estado canónico vs. heredado
  • Los usuarios no reciben ninguna indicación de que existe un estado histórico pero fue ignorado

🛠️ Solución paso a paso

Fase 1: Protección preventiva (Capa de andamiaje)

La lógica de andamiaje del espacio de trabajo debe verificar los registros heredados antes de crear un registro canónico nuevo.

Antes (andamiaje vulnerable):


function initializeWorkspace():
    canonicalRegistry = resolvePath("~/.openclaw/workspace/devclaw/projects.json")
    
    if not fileExists(canonicalRegistry):
        createDirectoryStructure()
        writeEmptyRegistry(canonicalRegistry)
        return
    
    loadRegistry(canonicalRegistry)

Después (andamiaje protegido):


function initializeWorkspace():
    canonicalRegistry = resolvePath("~/.openclaw/workspace/devclaw/projects.json")
    legacyRegistries = [
        resolvePath("~/.openclaw/workspace/projects.json"),
        resolvePath("~/.openclaw/workspace/projects/projects.json"),
        resolvePath("~/.openclaw/projects.json")
    ]
    
    if not fileExists(canonicalRegistry):
        // Check for orphaned legacy state
        existingLegacy = findFirstExisting(legacyRegistries)
        
        if existingLegacy is not null:
            throw MigrationRequiredError(
                "Legacy registry found at: " + existingLegacy.path + 
                ". Migrate before initializing fresh workspace."
            )
        
        createDirectoryStructure()
        writeEmptyRegistry(canonicalRegistry)
        return
    
    loadRegistry(canonicalRegistry)

Fase 2: Ruta de migración

Cuando se detecta estado heredado, proporcionar un comando de migración:

Comando CLI de migración:


# Detect and display legacy registry locations
$ devclaw registry diagnose

Registry Diagnostic Report
===========================
Canonical Path: ~/.openclaw/workspace/devclaw/projects.json
Status: MISSING

Legacy Registries Found:
  - ~/.openclaw/workspace/projects.json (MODIFIED: 2024-01-19 14:22)
  - ~/.openclaw/projects.json (MODIFIED: 2023-12-15 09:30)

To migrate legacy state:
  $ devclaw registry migrate --source ~/.openclaw/workspace/projects.json

To start fresh (WARNING: deletes legacy state):
  $ devclaw registry reset --force

Ejecución de la migración:


# Migrate from legacy location
$ devclaw registry migrate --source ~/.openclaw/workspace/projects.json

Migrating registry...
  Source: ~/.openclaw/workspace/projects.json
  Target: ~/.openclaw/workspace/devclaw/projects.json
  Projects to migrate: 5
  Channels to migrate: 12
  [████████████████████] 100%

Migration complete. 5 projects migrated successfully.

Fase 3: Verificación de la corrección


# Subsequent startup should not create empty registry when legacy exists
$ devclaw start

Error: Legacy registry detected at ~/.openclaw/workspace/projects.json
  Run 'devclaw registry migrate' before starting DevClaw.

# After migration, startup proceeds normally
$ devclaw registry migrate --source ~/.openclaw/workspace/projects.json
$ devclaw start
DevClaw initialized successfully.
  Projects: 5 registered
  Channels: 12 active

🧪 Verificación

Caso de prueba 1: Espacio de trabajo nuevo (sin heredado)


# Clean state: no canonical, no legacy
$ rm -rf ~/.openclaw/workspace/devclaw
$ rm -f ~/.openclaw/workspace/projects.json

$ devclaw start
DevClaw initialized successfully.
  Canonical registry created: ~/.openclaw/workspace/devclaw/projects.json

$ cat ~/.openclaw/workspace/devclaw/projects.json
{"projects":{}}

# Exit code
$ echo $?
0

Caso de prueba 2: Existe heredado, canónico faltante


# Setup: legacy exists, no canonical
$ mkdir -p ~/.openclaw/workspace
$ echo '{"projects":{"test-project":{"path":"/home/sai/test"}}}' > ~/.openclaw/workspace/projects.json
$ rm -rf ~/.openclaw/workspace/devclaw

$ devclaw start
# Should FAIL with migration error
Error: Legacy registry detected.
  Location: ~/.openclaw/workspace/projects.json
  Run: devclaw registry migrate

$ echo $?
1

# Verify empty canonical was NOT created
$ ls ~/.openclaw/workspace/devclaw/
ls: cannot access '~/.openclaw/workspace/devclaw/': No such file or directory

Caso de prueba 3: Después de una migración exitosa


$ devclaw registry migrate --source ~/.openclaw/workspace/projects.json
Migration complete.

$ devclaw start
DevClaw initialized successfully.

$ cat ~/.openclaw/workspace/devclaw/projects.json
{"projects":{"test-project":{"path":"/home/sai/test"}}}

$ devclaw projects list
test-project

Caso de prueba 4: Prevención de regresión


# Attempt to bypass migration by pre-creating empty canonical
$ echo '{}' > ~/.openclaw/workspace/devclaw/projects.json
$ devclaw start

# Should detect fork/inconsistency
Warning: Canonical registry is empty but legacy state exists.
  Canonical: ~/.openclaw/workspace/devclaw/projects.json
  Legacy:    ~/.openclaw/workspace/projects.json (2048 bytes)
  
  Run 'devclaw registry migrate' to reconcile.

$ echo $?
1

⚠️ Errores comunes

Trampas específicas del entorno

  • Inicialización de contenedor Docker: Cuando DevClaw se ejecuta dentro de Docker, las monturas de volumen pueden crear la estructura de directorios pero dejar projects.json faltante. El andamiaje del punto de entrada del contenedor bifurcará el estado si existe un heredado en el volumen del host.
  • Mayúsculas y minúsculas en macOS: El sistema de archivos es insensible a mayúsculas por defecto. projects.json y Projects.json pueden existir ambos en diferentes ubicaciones heredadas, causando comportamiento confuso durante el diagnóstico.
  • Resolución de rutas en Windows: Las rutas heredadas pueden usar barras invertidas o separadores mixtos. La protección debe normalizar las rutas antes de la comparación.
  • Sistemas de archivos de red (NFS): Las verificaciones de existencia de archivos pueden competir con escrituras concurrentes. Usar bloqueo de archivos u operaciones atómicas al verificar y crear registros.

Configuraciones incorrectas del usuario

  • Migración parcial: Los usuarios pueden ejecutar devclaw registry migrate sin especificar la ruta de origen correcta, migrando desde una ubicación heredada vacía mientras existe otra heredada poblada en otro lugar.
  • Edición manual del estado: Los usuarios que editen projects.json manualmente pueden crear errores de sintaxis JSON, causando que la migración falle silenciosamente y cree un registro canónico vacío.
  • Confusión con enlaces simbólicos: Los enlaces simbólicos a rutas heredadas o canónicas pueden confundir la lógica de detección. Implementar resolución realpath antes de las comparaciones.
  • Problemas de permisos: Si el usuario carece de permisos de escritura para crear devclaw/projects.json, el andamiaje puede fallar sin un mensaje de error claro, o puede crear el directorio pero no el archivo.

Casos extremos

  • Archivo heredado de cero bytes: Un projects.json heredado que existe pero está vacío (0 bytes) debe tratarse de manera diferente a un archivo faltante. La protección debe distinguir entre "sin heredado" y "heredado vacío".
  • JSON heredado corrupto: Si el heredado contiene JSON mal formado, la migración debe fallar con un error específico en lugar de volver a crear un registro canónico vacío.
  • Instancias concurrentes de DevClaw: Múltiples instancias de DevClaw iniciando simultáneamente pueden competir para crear el registro vacío. Usar bloqueo de archivos (flock) durante la inicialización.
  • Migración interrumpida a mitad de escritura: Si el proceso de migración se interrumpe después de copiar el heredado pero antes de actualizar el estado interno, el sistema puede quedar en un estado inconsistente. Implementar escrituras atómicas o registros de transacciones.

🔗 Errores relacionados

Códigos de error lógicamente conectados

  • REGISTRY_NOT_FOUND: La ruta del registro canónico no existe y no hay alternativa disponible
  • REGISTRY_CORRUPTED: El archivo del registro existe pero contiene JSON inválido
  • LEGACY_REGISTRY_DETECTED: Se encontró una ubicación de registro heredado durante la inicialización; se requiere migración
  • MIGRATION_IN_PROGRESS: La migración del registro falló o fue interrumpida
  • PROJECT_NOT_REGISTERED: La búsqueda del proyecto falló porque está ausente del registro
  • CHANNEL_ROUTING_FAILED: El enrutamiento de tareas falló debido a metadatos de proyecto faltantes
  • WORKSPACE_INIT_FAILED: El andamiaje no pudo crear la estructura de directorio requerida

Problemas históricos

  • Issue #142: "Project registry intermittently empty after system restart" - Informe de síntoma temprano que expuso este comportamiento de bifurcación silenciosa
  • Issue #156: "Channel routing fails for all projects on fresh session" - Consecuencia posterior del registro canónico huérfano vacío
  • Issue #167: "Migration command does not detect all legacy paths" - Corrección incompleta de la ruta de migración
  • Issue #189: "Docker volume mounting causes registry state loss" - Manifestación específica del entorno de la misma causa raíz

Lista de verificación de prevención


# Pre-flight check before upgrading DevClaw
$ devclaw registry pre-flight-check

Running pre-flight checks...
[✓] Verifying canonical registry path accessibility
[✓] Checking for legacy registry locations
[✓] Validating registry JSON integrity
[✓] Confirming write permissions

Pre-flight complete. No issues detected.

# If issues detected:
$ devclaw registry pre-flight-check --verbose

Running pre-flight checks...
[✓] Canonical: ~/.openclaw/workspace/devclaw/projects.json (exists)
[⚠] Legacy detected: ~/.openclaw/workspace/projects.json (2048 bytes)
[!] Action required: Run 'devclaw registry migrate' before upgrading

Evidencia y fuentes

Esta guía de solución de problemas fue sintetizada automáticamente por la tubería de inteligencia de FixClaw a partir de las discusiones de la comunidad.