Troubleshooting
Comparisons
A compare shows hundreds of differences in an object nobody
changed. Check that the compare is parsed rather than text. A
flat list of lines instead of a hierarchy tree means the file did not
parse: a file name whose extension names the wrong type, so that the
$PBExportHeader$ fallback never runs (add
-Detect H), or a genuinely corrupt file. If the hierarchy
is there and the noise is in a DataWindow, check the two DataWindow case
normalisations, which are on by default. If the noise comes from
indentation, tick Ignore whitespace. See Take the noise
out.
A function shows as deleted and a nearly identical one as added. Its signature changed, and Automatically sync modified function and event names has been turned off. It is on by default and would have paired the two as one modification. Tick it again in Options ▸ PowerBuilder.
Two unrelated lines are shown as a modification of one another, or a long run of changes reads as one big deletion plus one big addition. That is the Resync distance threshold deciding how alike two lines must be to count as an edit. Raise it to stop weak pairings, lower it to pair more aggressively, set it to 0 to disable the check.
A function shows as modified but its body looks identical. Read the signature strip below the compare panes: it shows the old and the new signature, and the change is in the parameter list or the return type. View ▸ Signatures shows and hides the strip.
Comparing two .pbd files tells me an object
changed but not what changed. That is expected and is not a
defect: a .pbd holds compiled P-code, and pb-diff does not
decompile it. Compare the .pbl files or the exported
sources instead. See Reading
PowerBuilder libraries.
A library will not open, or an entry will not
export. Run Tools ▸ Validate Library, or
pb-diff-cli validate <library>. It walks the
structure and reports findings with stable codes; the CLI exits with 0
when the library is clean, 1 for warnings only and 2 when it is damaged.
A library the IDE can still open may nevertheless carry structural
damage worth knowing about. Check
libraries for damage says what each code means and what to do about
it, and how to check every library of an application at once.
Source-control clients and the IDE
The diff tool in my source-control client opens a text
compare, not a parsed one. A temporary file with an
unrecognised extension such as .tmp or .r412
is not the cause: pb-diff reads the $PBExportHeader$ line
for those files without being told to. The cause is an extension that
names the wrong type, or a file with no export header. Add
-Detect H to the configured command line so the header is
read before the name is consulted at all, or -Detect F if
the client appends a suffix to the real name. See Clients
that mangle file names.
The client launches pb-diff but the window never appears, or
appears empty. Check the quoting of the placeholders: an
unquoted path with a space arrives as two arguments, and pb-diff opens
on an empty window saying how to start. Adding -SDI makes
the comparison the only thing in the window, which is what a diff tool
should do.
PowerBuilder's Git Diff or SVN Diff opens Tortoise's own viewer, or a comparison with one side missing. If Tortoise opens its own viewer, check the extension entry in Tortoise and the Windows account it was registered under. If a direct launch lacks one input, check Other, the saved executable path and the full two-placeholder argument line. See Check the configuration and its limits.
A script starts pb-diff.exe and carries on
before the window is closed. pb-diff.exe is a
Windows program, so a command prompt or PowerShell starts it and
returns. Use start "" /wait pb-diff.exe … or
Start-Process -Wait; see Waiting
for the window, and exit codes. A source-control client waits
without being told.
pb-diff.exe -Help shows a message box instead of
printing. Nothing captured its output. Redirect it,
pb-diff.exe -Help > usage.txt, or pipe it to
more.
A build script hangs waiting for something. It is
calling pb-diff.exe, the desktop application. Call
pb-diff-cli.exe instead: it has no user interface, cannot
prompt, and reports its result as an exit code.
PowerBuilder 2025 Solutions
A merged source fails to build with "UTF-16 (LE) byte order mark detected". The file in the PBL folder is UTF-16LE, which the Solution compiler does not read. pb-diff writes UTF-8 whenever the file its merge rewrites is UTF-8, so the file came from a merge whose rewritten side was a library export, or from another tool. Merge again with the Solution source on the New side (two-way) or as the Base (three-way), or re-save the file as UTF-8.
pb-diff-cli says a .pbl is "a
PowerBuilder Solution library folder". In a Solution,
app.pbl is a folder holding one source per object, not a
library file. Name the .sr* files inside it, compare the
two folders with pb-diff-cli compare-lib, or compare them
in a File Selection in the desktop application.
A Solution source opened from a client compares as plain
text. Its name carries no type, and it is an object inherited
from another object of your application, which nothing in the file
identifies. Keep the real extension in the name, or add
-Detect F if the client appends a suffix to it.
Merges
A merged file will not import into PowerBuilder.
Read the warnings pb-diff produced during the merge: a script referring
to a function or control that did not come across is the usual cause. If
a control is involved, check that you brought its property block and its
declarations. pb-diff maintains the .create and
.destroy scripts and the control list, but it will not
invent a property block you did not restore. See The four places a
control lives.
The window and the settings
A command I expect is missing from the tool bar. Either the window is too narrow for the whole bar, in which case what does not fit is under the chevron at its right-hand end, or the tab in front does not have that command. A button that shows an icon and no name is not missing: in a narrow window the buttons give up their names before any of them is moved, and the tool tip still names each one. The bar carries the commands of the tab in front and nothing else, so the buttons change when you switch tabs. The menu bar always lists every command pb-diff has, greyed out when the tab in front cannot carry it out.
The window is off-screen or at an unusable size. Options ▸ Window settings and its Reset the main window button. If it is a splitter inside a tab rather than the window, Reset Document pane layouts in the same place.
A portable copy is not remembering my settings. The
folder it was unzipped into is probably read-only, such as
Program Files, a share or read-only media. The status bar
says so when you press OK in Options. Unzip it somewhere writable, or
drop --portable and remove the settings.json
beside the executable, which is used in preference to the one in your
profile.
Settings are not being remembered on a shared or locked-down
machine. %APPDATA%\pb-diff\settings.json may not
be writable. Put a settings.json beside the executable
instead: it is used in preference to the per-user one. See Settings and profile files.
pb-diff opens yesterday's comparison when I start it. That is Reopen the comparison left open, and the last file selection, which is on by default: the comparison in front when pb-diff was closed is reopened by a launch with nothing else to do. Close its tab before exiting and the next start opens nothing; clear the option on the General page of Tools ▸ Options to never reopen one; or give pb-diff files on the command line, which always wins.
Worked examples
Run these commands from the docs\examples\order-desk
folder of the installation. Each links to its result.
DataWindow attribute case.
datawindow/case-only/d_order_lines.srd is release 1.4's
d_order_lines with attribute names such as
color spelt COLOR, and no value changed. The
default normalisation reports no difference (exit 0, result);
disabling it reports twelve modified items (exit 1, result):
pb-diff-cli compare old/d_order_lines.srd datawindow/case-only/d_order_lines.srd --format json
pb-diff-cli compare old/d_order_lines.srd datawindow/case-only/d_order_lines.srd --no-normalise-case --format json
Temporary and misleading extensions.
temporary/3f9a2c.tmp has no recognised type, so pb-diff
reads its export header without being told to.
temporary/n_order_service.xml has a recognised but wrong
type, so its parse falls back to text; --detect H makes the
header take precedence:
pb-diff-cli parse temporary/3f9a2c.tmp --format json
pb-diff-cli parse temporary/n_order_service.xml --format json
pb-diff-cli parse temporary/n_order_service.xml --detect H --format json
All three return exit code 0. Read usedFallback and the
diagnostics as well: the middle
result reports parse.fallback, while the first and
the last
identify n_order_service as a user object.
Source and compiled entries. The Order Desk
libraries hold source entries. formats/compiled.pbd holds
one compiled function and nothing else, as a .pbd does (source, compiled,
bytes):
pb-diff-cli list libraries/release-1.5/orders.pbl --format json
pb-diff-cli list formats/compiled.pbd --format json
pb-diff-cli compare-lib formats/compiled.pbd formats/compiled.pbd --mode binary --format json
The last command compares the PBD with itself and reports identical
bytes. It does not recover PowerScript or prove source equivalence. For
a function-level explanation of changes between releases, use a PBL
containing source or exported .sr* files.