siyuan-note/siyuan · error
parse imported notebook conf
Error message
parse imported notebook conf [%s] failed: %w
What it means
In validateImportedNotebookIdentities, after successfully reading an imported notebook's .siyuan/conf.json, the JSON must unmarshal into a conf.BoxConf. If the content is not valid JSON or has an incompatible shape, the function returns 'parse imported notebook conf [%s] failed' wrapping the unmarshal error, because boxConf fields (including Encrypted/BoxCrypt identity) cannot be trusted.
Solutions
- Open the imported notebook's .siyuan/conf.json and validate it as JSON (e.g. jq .); fix syntax errors if hand-edited.
- Re-export or re-download the notebook archive from the source workspace to get an intact conf.json.
- If only that notebook is corrupt, remove it from the import set, import the rest, then restore the notebook from a SiYuan snapshot/history backup.
- Compare with a valid conf.json from a working notebook to restore required fields (name, encrypted, etc.).
Defensive patterns
Strategy: validation
Validate before calling
const raw = await fs.promises.readFile(path.join(boxDir, '.siyuan', 'conf.json'), 'utf8'); JSON.parse(raw); // throws SyntaxError before the API call if the conf is malformed
Type guard
function isValidBoxConf(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v) && typeof v.name === 'string';
} Try / catch
try {
await importData(src);
} catch (e) {
if (/parse imported notebook conf/.test(e.msg)) {
console.error('Validate/repair .siyuan/conf.json JSON, or re-export the notebook');
}
throw e;
} Prevention
- Never hand-edit conf.json without re-validating as JSON
- Validate every notebook's conf.json in an archive before importing
- Re-export from a healthy source workspace instead of repairing corrupt archives
When it happens
Trigger: ImportData importing a notebook whose .siyuan/conf.json is corrupt, truncated, hand-edited to invalid JSON, or produced by an incompatible tool/older format that gulu.JSON.UnmarshalJSON cannot decode into conf.BoxConf.
Common situations: 1) Archive extraction truncated by low disk space. 2) conf.json edited manually and saved with a syntax error. 3) Third-party tool writing a differently shaped conf.json. 4) Binary corruption from a failed sync/transfer.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- read imported notebook conf
- This is not a valid .sy.zip archive. If the archive was…
- 199
- builtin color must not be null
- builtin style must not be null
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/702b2a49881ef42f.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/import.go:1340
for _, entry := range dirs {
if !entry.IsDir() || !ast.IsNodeIDPattern(entry.Name()) {
continue
}
boxID := entry.Name()
boxDir := filepath.Join(tmpDataPath, boxID)
confPath := filepath.Join(boxDir, ".siyuan", "conf.json")
backupPath := filepath.Join(boxDir, ".siyuan", notebookCryptoBackupFilename)
var boxConf *conf.BoxConf
if filelock.IsExist(confPath) {
data, readErr := filelock.ReadFile(confPath)
if readErr != nil {
return nil, fmt.Errorf("read imported notebook conf [%s] failed: %w", boxID, readErr)
}
boxConf = conf.NewBoxConf()
if unmarshalErr := gulu.JSON.UnmarshalJSON(data, boxConf); unmarshalErr != nil {
return nil, fmt.Errorf("parse imported notebook conf [%s] failed: %w", boxID, unmarshalErr)
}
}
var backup *conf.BoxEncryption
if filelock.IsExist(backupPath) {
backup, err = readBoxEncryptionFile(backupPath)
if err != nil {
return nil, fmt.Errorf("invalid imported notebook identity [%s]: %w", boxID, err)
}
}
var boxCrypt *conf.BoxEncryption
if boxConf != nil && boxConf.Encrypted {
if boxConf.BoxCrypt != nil && validateBoxEncryption(boxConf.BoxCrypt) == nil {
boxCrypt = boxConf.BoxCrypt
} else {
boxCrypt = backup
}View on GitHub (pinned to 9f775e8a12)