{"record":{"id":"36049e1645a25731","repo":"xpipe-io/xpipe","slug":"encrypted-value-is-null","errorCode":null,"errorMessage":"Encrypted value is null","messagePattern":"Encrypted value is null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/storage/DataStoreEntryNode.java","lineNumber":38,"sourceCode":"        var type = TypeFactory.createDefaultInstance().constructParametricType(OptionalEncryptedValue.class, clazz);\n        OptionalEncryptedValue<T> enc = JacksonMapper.getDefault().readValue(file.toFile(), type);\n        return enc != null ? new DataStoreEntryNode<>(enc, true) : null;\n    }\n\n    public static <T> DataStoreEntryNode<T> of(T value) {\n        return value != null ? new DataStoreEntryNode<>(OptionalEncryptedValue.ofRaw(value), false) : null;\n    }\n\n    public static <T> DataStoreEntryNode<T> ofWritten(T value) {\n        return value != null ? new DataStoreEntryNode<>(OptionalEncryptedValue.ofRaw(value), true) : null;\n    }\n\n    private final OptionalEncryptedValue<T> enc;\n    private boolean written;\n\n    private DataStoreEntryNode(OptionalEncryptedValue<T> enc, boolean written) {\n        if (enc == null) {\n            throw new IllegalArgumentException(\"Encrypted value is null\");\n        }\n\n        this.enc = enc;\n        this.written = written;\n    }\n\n    public T reparseValue(Class<T> clazz) {\n        var newValue = enc.reparseValue(clazz);\n        // Keep existing object if possible\n        return Objects.equals(enc.getValue(), newValue) ? enc.getValue() : newValue;\n    }\n\n    public DataStoreEntryNode<T> prepareForWrite(DataStoreEntry entry, boolean encryptIfRestricted, T newValue) {\n        var targetScope = DataStoreAccessScope.getTargetScope(entry.getAccessScope());\n        var currentScope = enc.getSecret() != null ? enc.getSecret().getScope() : targetScope;\n\n        var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessSubRestricted())\n                || AppPrefs.get().encryptAllVaultData().get();","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/storage/DataStoreEntryNode.java#L20-L56","documentation":"DataStoreEntryNode wraps an OptionalEncryptedValue that holds a store's serialized data, and its constructor requires a non-null wrapper. Passing null throws IllegalArgumentException — the node cannot represent an entry without its (possibly empty) encrypted value container.","triggerScenarios":"Calling the private factory DataStoreEntryNode.of(...) path / constructor with a null OptionalEncryptedValue, e.g. when serializing a DataStoreEntry whose encrypted-value field was never initialized or was lost during deserialization of a corrupted vault node.","commonSituations":"Vault JSON where the encrypted value field is absent/null for an entry; entries loaded from an older format or partially failed migration; code constructing entry nodes directly instead of through the official factory.","solutions":["Always initialize the entry's OptionalEncryptedValue (use the empty wrapper, not null) before creating a DataStoreEntryNode.","Check how the encrypted value became null — repair or re-save the affected vault entry.","Construct nodes only via DataStoreEntryNode.of(...) and ensure that path never receives null."],"exampleFix":"// before\nDataStoreEntryNode.of(entry.getEncryptedValue()); // NPE-ish throw when null\n// after\nvar enc = entry.getEncryptedValue() != null ? entry.getEncryptedValue() : OptionalEncryptedValue.empty();\nDataStoreEntryNode.of(enc);","handlingStrategy":"type-guard","validationCode":"if (entry.getEncryptedValue() == null) {\n    entry.setEncryptedValue(OptionalEncryptedValue.empty());\n}","typeGuard":"boolean nodeReady(DataStoreEntry e) { return e.getEncryptedValue() != null; }","tryCatchPattern":"try {\n    DataStoreEntryNode.of(enc);\n} catch (IllegalArgumentException e) {\n    // rebuild the node from an empty encrypted value\n}","preventionTips":["Never store null for the encrypted-value wrapper; use an empty instance.","Validate vault JSON on load and repair missing encrypted-value fields.","Always go through the official factory methods instead of direct construction."],"tags":["java","illegal-argument","null-value","serialization"],"backgroundTag":"null-argument","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}