BCCL Documentation
Index

Import (PUTDATA) Errors

This page covers errors raised by Business Central while BCCL imports records with the putdata task. The most common case is a "must have a value" error on a field that clearly has a value in your input file. The sections below explain why that happens, how to diagnose it, and which remedies work in which order.


"\ must have a value in \ ... It cannot be zero or empty"

Symptom

A putdata run fails with an error of this form, even though the input file visibly contains a value for the field named in the message:

<Field> must have a value in <Table>: <Field>=, <Key>=<value>. It cannot be zero or empty.

An anonymised real-world example from table 349 (Dimension Value):

Error: Dimension Code must have a value in Dimension Value: Dimension Code=, Code=<value>. It cannot be zero or empty.

with a stack trace of the form:

Table 349.OnInsert(Trigger)
CodeUnit 80806.ImportTableJson
CodeUnit 80806.OnRun
CodeUnit 80807.HandleRequest
CodeUnit 80800.call

Note where the failure occurs: in the target table's CheckField / OnInsert(Trigger). The error is raised by the target table's own code, not by BCCL. BCCL's objects (codeunits 80806, 80807, 80800) appear lower in the trace because they called into the table.

First Diagnostic Step

Run the import with verbose mode (-v) and look at the Content: line that BCCL prints for the failing record. This is the JSON payload BCCL sent to Business Central.

  • If the field named in the error is present with a value in that payload, the source data and the mapping are not the problem. Continue with the remedy procedure below.
  • If the field is missing or empty in the payload, the problem is in your input file or in the MappedName values of the mapping file.

Why It Happens

Two different causes produce the same message:

  1. A Function entry conflicts with validation. A mapping entry such as "Function":"CONST(<value>)" on a field that Business Central validates can leave the field empty at insert time. In the words of support: "the function fights the validate."
  2. The table's OnInsert trigger requires a non-primary-key field. BCCL inserts the record and then assigns the remaining fields. If the target table's OnInsert trigger requires a field that is not part of the primary key to already be filled, the insert fails before BCCL has assigned that field.

Remedy Procedure

Work through these steps in order:

  1. Check the mapping for a Function entry on the field named in the error. If the mapping contains something like "Function":"CONST(...)" for that field and the value is already present in the input data, do not use CONST. Map it as a regular field mapping (FieldNo, FieldName, MappedName, optionally Validate). CONST is only for supplying a value that is not in the input data. Removing the CONST entry and using a plain field mapping is the recommended fix for this error.

Before:

   {"FieldNo": 1, "FieldName": "Dimension Code", "MappedName": "Dimension Code", "Function": "CONST(<value>)", "Validate": true}

After:

   {"FieldNo": 1, "FieldName": "Dimension Code", "MappedName": "Dimension Code", "Validate": true}
  1. Use delayed insert (-d). Add -d to the putdata command line:
   BCCL -t putdata -s table=<TableNo> -i <input.json> -f json -m <mapping.json> -d

The -d parameter is designed for exactly the case where the target table's OnInsert trigger requires a non-primary-key field to be filled with a value. It corresponds to the "DelayedInsert": true entry shown in the verbose settings output (the default is false). See "Delayed Insert (-d)" below.

  1. Only if -d is not viable: set "ValidateOnInsert": false in the mapping file. Some tables have complex OnInsert logic whose triggers re-validate or re-derive field values; table 349 Dimension Value is a concrete example. Setting ValidateOnInsert to false makes the import succeed, but it bypasses the table's insert-time validation entirely. Treat it as a last-resort escape hatch, not as the standard fix.
  2. Confirm that the mapping file is the cause. Re-run the same putdata command without -m. If it succeeds, the mapping file is at fault (most commonly a CONST entry on a validated field), not the putdata command itself.
  3. Do not chase the table key spelling. Correcting the formatting of the mapping file's top-level table key (for example changing "Dimension_Value" to "Dimension Value") does not by itself resolve this error. This was tested in the field and the error persisted.

What Does Not Fix It

Based on real cases, the following changes make no difference to this error:

Change Effect
Setting "Validate": true on the field named in the error Error is identical
Setting "Validate": false on the field named in the error Error is identical
Changing the order of the fields in the mapping file Not the cause
Re-spelling the top-level table key in the mapping file Not the cause

About Configuration Packages

If the same data can be imported with a standard Business Central Configuration Package, that does not indicate a defect in BCCL. Configuration packages assign the fields before inserting the record, which is exactly what delayed insert (-d) makes BCCL do.

Observed Environment

This behaviour was confirmed with BCCL app version 3.23.0.372 against a Business Central 14 service tier on table 349. The mechanism is not version-specific; any table whose OnInsert trigger enforces a non-key field behaves the same way.


Delayed Insert (-d)

-d (long form --delayedinsert) enables the delayed insert pattern for putdata.

Property Value
Short form -d
Long form --delayedinsert
Default false
Shown in verbose settings as "DelayedInsert": true
Applies to putdata

Purpose: -d exists for the case where the target table's OnInsert trigger requires a non-primary-key field to be filled with a value. With delayed insert, BCCL assigns the field values before the record is inserted, so the trigger sees a complete record.

When to add it: whenever an import fails inside the target table's OnInsert trigger with a "must have a value / cannot be zero or empty" error for a field that is present in the payload.

How it relates to validation settings: -d is orthogonal to the per-field Validate property and to ValidateOnInsert / ValidateOnModify. It changes when the record is inserted, not whether validation runs.


Scope of Validate, ValidateOnInsert and ValidateOnModify

The mapping file offers validation controls at two levels. Understanding what each one can and cannot influence saves time when an insert fails.

Setting Where What it controls What it cannot influence
Validate Per field Whether that field's OnValidate logic runs when BCCL assigns it Errors raised by the table's OnInsert trigger, because the insert happens before non-key fields are assigned (unless -d is used)
ValidateOnInsert Root of mapping file Whether the target table's insert-time validation (OnInsert) runs Nothing else; setting it to false skips the business logic in OnInsert entirely
ValidateOnModify Root of mapping file Whether the target table's modify-time validation (OnModify) runs Same limitation as ValidateOnInsert, for updates
ValidateOnDelete Root of mapping file Whether delete triggers run during delete operations Import behaviour

Disabling ValidateOnInsert, ValidateOnModify or ValidateOnDelete means the values from the input file are written without Business Central's validation logic being triggered. Records may end up in a state the owning app does not expect.

Recommended order of remedies for insert-trigger errors:

  1. -d (delayed insert).
  2. Only if that is not viable, "ValidateOnInsert": false.

Using a Mapping File with putdata

Mapping files are supported and normal for putdata; they are not discouraged. Passing -m <mappingfile.json> is optional, but it is the recommended way to control which columns map to which fields.

The same mapping file can be used for a getdata → putdata round trip. A generic, anonymised example of that pattern:

BCCL -w <webservice-url> -t getdata -s table=349 "view=WHERE(Field1=1(CONTRACT))" -o <output.json> -f json -m <mapping.json> -v
BCCL -w <webservice-url> -t putdata -s table=349 -i <output.json> -f json -m <mapping.json> -v

where <webservice-url> has the form http://<server>:<port>/<instance>/WS/<company>/Codeunit/bccl for on-premises environments.

If a putdata run fails with a mapping file but succeeds without it, the problem is in the mapping file (most commonly a "Function":"CONST(...)" entry on a validated field, see above), not in the putdata command itself.


Importing into Tables from Third-Party Apps

Tables published by third-party Business Central apps frequently carry mandatory non-primary-key fields that are enforced in the table's OnInsert trigger.

A generalised pattern: the table's primary key is a set of code fields, but its OnInsert trigger calls a CheckField routine that requires a separate reference field (for example a "No." field tied to a "Type" option) to be non-empty. A plain insert with only the primary key filled fails immediately.

Recommendation: for such tables, run putdata with -d from the start rather than waiting for the error.

Reading the Stack Trace

The stack trace in the BCCL error output tells you which app and which table raised the error:

  • The trace lines name the object, the trigger (for example OnInsert) and the publishing app with its version.
  • BCCL's own objects (codeunits in the 80800 range) appear lower in the trace, because they called into the table.

Use this to decide whether the error originates in BCCL or in the target app's table code. In the cases on this page, the topmost lines point at the target table, so the fix is on the import side (-d, mapping) rather than in BCCL itself. For a general walkthrough of reading AL call stacks, see Identifying Which App Raised an Error.


Quick Reference

Symptom Likely cause First action
"must have a value ... cannot be zero or empty" with the value present in Content: OnInsert requires a non-key field before BCCL assigns it Add -d
Same error, mapping has CONST(...) on the named field Function conflicts with validation Replace with a plain field mapping
Same error, table has complex OnInsert logic and -d is not viable Insert-time validation "ValidateOnInsert": false (last resort)
Import works without -m, fails with -m Mapping file error Inspect the mapping, especially Function entries
Field missing or empty in Content: Input data or MappedName mismatch Fix the input file or the mapping