siyuan-note/siyuan · error
newPath is required
Error message
newPath is required
What it means
When performing an actual relink (lookup mode is false), every mapping must carry a NewPath: a relink defines where the old asset should move. A mapping whose NewPath is empty is recorded as an inputError on the item and reported with this message; in lookup mode (FindAssetReferences*) empty NewPath is allowed.
Solutions
- Fill in NewPath for every mapping before calling the relink functions
- Use the lookup APIs (FindAssetReferences*/lookup mode) when you only want references, not a move
- Validate the payload client-side so rows without newPath are rejected before submission
Example fix
// before
mappings := []apicontract.AssetRelinkMapping{{OldPath: "assets/a.png"}}
model.RelinkAssets(ctx, mappings, false)
// after
mappings := []apicontract.AssetRelinkMapping{{OldPath: "assets/a.png", NewPath: "assets/b.png"}}
for _, m := range mappings {
if m.NewPath == "" { return errors.New("newPath required for " + m.OldPath) }
}
model.RelinkAssets(ctx, mappings, false) Defensive patterns
Strategy: validation
Validate before calling
for _, m := range mappings {
if !lookup && m.NewPath == "" { return fmt.Errorf("newPath required for %q", m.OldPath) }
} Type guard
if !lookup && mapping.NewPath == "" { return false } Prevention
- Distinguish find (lookup) vs relink endpoints and their required fields
- Validate each row in batch UI before submission
- Use dry-run first to catch per-item input errors safely
When it happens
Trigger: Calling RelinkAssetWithContext or RelinkAssets (dryRun true or false) with any mapping whose NewPath field is an empty string; lookup calls (FindAssetReferencesBatch) are exempt.
Common situations: Client built request for the find/references endpoint but sent it to the relink endpoint; JSON payload omitted newPath for some entries; batch UI left a row half-filled.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- all asset mappings failed
- assetPath is not an image referenced by the document
- assetPath is required for analyze
- at least one asset path or mapping is required
- binary files cannot be edited as text
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/491475ae16f848f4.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/asset_relink_batch.go:77
func RelinkAssets(ctx context.Context, mappings []apicontract.AssetRelinkMapping, dryRun bool) (apicontract.AssetReferencesData, error) {
return runAssetRelinks(ctx, mappings, dryRun, false, true)
}
func newAssetRelinkPlan(ctx context.Context, mappings []apicontract.AssetRelinkMapping, dryRun, lookup, batch bool) (*assetRelinkPlan, error) {
p := &assetRelinkPlan{ctx: ctx, batch: batch, lookup: lookup, assetRelinker: &assetRelinker{
collectOnly: true, routes: map[string]*assetRelinker{},
result: apicontract.AssetReferencesData{References: []apicontract.AssetReference{}, SkippedNotebooks: []string{}, DryRun: dryRun},
}}
if len(mappings) == 0 {
return p, errors.New("at least one asset path or mapping is required")
}
seen := map[string]bool{}
var validationErr error
for _, mapping := range mappings {
rule, err := newAssetRelinker(mapping.OldPath, mapping.NewPath)
if !lookup && mapping.NewPath == "" {
err = errors.New("newPath is required")
}
item := &assetRelinkItem{input: mapping, rule: rule}
p.items = append(p.items, item)
if rule.oldPath != "" {
if seen[rule.oldPath] {
validationErr = fmt.Errorf("duplicate oldPath: %s", mapping.OldPath)
}
seen[rule.oldPath] = true
}
if err != nil {
item.inputError = true
p.fail(item, err.Error())
continue
}
p.routes[rule.oldPath] = rule
}
if validationErr != nil {
return p, validationErrView on GitHub (pinned to 9f775e8a12)