{"record":{"id":"94ec20bc45258e16","repo":"dgtlmoon/changedetection.io","slug":"disk-full-cannot-save-label","errorCode":null,"errorMessage":"Disk full: Cannot save {label}","messagePattern":"Disk full: Cannot save (.+?)","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"critical","filePath":"changedetectionio/store/file_saving_datastore.py","lineNumber":157,"sourceCode":"#                f\"dir_fsync={dir_fsync_ms:.1f}ms, using_orjson={HAS_ORJSON}\"\n#            )\n\n    except OSError as e:\n        # Cleanup temp file\n        if not fd_closed:\n            try:\n                os.close(fd)\n            except:\n                pass\n        if os.path.exists(temp_path):\n            try:\n                os.unlink(temp_path)\n            except:\n                pass\n\n        # Provide helpful error messages\n        if e.errno == 28:  # ENOSPC\n            raise OSError(f\"Disk full: Cannot save {label}\") from e\n        elif e.errno == 122:  # EDQUOT\n            raise OSError(f\"Disk quota exceeded: Cannot save {label}\") from e\n        else:\n            raise OSError(f\"I/O error saving {label}: {e}\") from e\n\n    except Exception as e:\n        # Cleanup temp file\n        if not fd_closed:\n            try:\n                os.close(fd)\n            except:\n                pass\n        if os.path.exists(temp_path):\n            try:\n                os.unlink(temp_path)\n            except:\n                pass\n        raise e","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/dgtlmoon/changedetection.io/blob/5d9c7c6da76340597243e8163c4f2439237fa0e8/changedetectionio/store/file_saving_datastore.py#L139-L175","documentation":"An OSError raised by save_json_atomic in the file-based datastore when writing the temp JSON file fails with errno 28 (ENOSPC, no space left on device). The label identifies which file (settings or a watch entity) failed to save; the temp file is cleaned up before raising.","triggerScenarios":"Any settings or watch save (_save_settings, save_entity_atomic) hitting a full disk/partition while writing/flushing the temp file — the flush/fsync inside the atomic-write helper raises ENOSPC and is translated to this friendly message.","commonSituations":"Long-running containers accumulating snapshot history and JSON until the volume fills; small Docker volumes or tmpfs; CI boxes with tight disk quotas; huge numbers of watches inflating url-watches.json.","solutions":["Free disk space: remove old snapshots (docker volume prune / trim watch history), delete unused watches, clear logs","Grow the volume or move the datastore path to a larger disk","Enable the setting to limit snapshot/history retention so growth is bounded","After freeing space, verify saves succeed by triggering a check and confirming no error re-appears"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import shutil\nif shutil.disk_usage(datastore_path).free < 100 * 1024 * 1024:\n    alert('datastore volume nearly full')","typeGuard":null,"tryCatchPattern":"try:\n    datastore.save_entity_atomic(uuid, data)\nexcept OSError as e:\n    if 'Disk full' in str(e):\n        alert_ops('ENOSPC on datastore volume'); cleanup_old_snapshots()","preventionTips":["Monitor free space on the datastore volume with alerts at ~10% remaining","Enable snapshot/history retention limits so growth is bounded","Keep the datastore on a dedicated volume so logs can't fill it first"],"tags":["enospc","disk-full","datastore","io"],"backgroundTag":"disk-full","analyzedSha":"5d9c7c6da76340597243e8163c4f2439237fa0e8","analyzedAt":"2026-08-27T19:41:16.067Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}