The path \\machine\c$\Logs\03_filename.log fails in an Ignition script because the Jython parser turns \03 into a single control character (code point 3) before open() sees the string. The error text shows it as \x03_filename.log. A file named 31_filename.log shows \x19 for the same reason. The file system never gets the name you typed.
Quote swaps, string splits and file renames that leave the path broken
Three changes get tried first for this symptom. None of them fixes the path, and one of them hides the fault.
| Attempted fix | Result | Why it fails |
|---|---|---|
| Switch between single and double quotes | Same \x03 error |
Python treats '...' and "..." the same way. Both decode escape sequences. |
Insert a quote after Logs
|
\x disappears, but so does the backslash (Logs03_filename.log) |
\' is also an escape sequence. It consumes the backslash and produces a literal quote. |
| Split the path and concatenate the pieces | Original error, or stray spaces | Any fragment that still contains \0–\7 gets decoded when that fragment is parsed. Joining the pieces afterwards changes nothing. |
| Rename the file without the numeric prefix | File opens | The digits are removed, so no octal escape forms. The next file whose name starts with n, t, r, f, a, b, v or x breaks again. |
Backslash escape decoding in Jython string literals
Ignition runs scripts in Jython, which follows Python 2 string-literal rules. A backslash followed by 1–3 octal digits (0–7) is replaced by one character whose value is that octal number. The quantity that decides the case is the length of the decoded string. \03 is three typed characters but becomes one character at runtime. The count shrinks before any file I/O happens.
Fragment after Logs
|
Decoded as | Value | Effect on the path |
|---|---|---|---|
\x + non-hex |
invalid escape | n/a | Script fails to compile |
\m, \c, \L
|
not an escape | unchanged | Backslash kept, which is why the rest of the path looked correct |
A leading \\ is also an escape. It collapses to one backslash, so a UNC path typed with two leading backslashes reaches the OS with one. That is a relative path, not a network share.
Every day-of-month prefix from 01 to 31 produces an octal escape or a null. A daily log file will fail on every day of the month, not only on specific days.
Diagnosing the decoded path with repr() and os.path
This error has two possible causes, and they are separate problems:
- Literal fault: the string itself is corrupted by escape decoding.
- Access fault: the path is correct, but the host running the script cannot reach it.
Run these checks in the Script Console to tell them apart:
- Print
repr(filepath). Any\x..,\t,\nor\x00in the output confirms a literal fault. - Print
len(filepath)and compare it with the number of characters you intended. A shorter count confirms decoding ate characters. - Print
os.path.exists(filepath). It returnsFalsefor both faults. Only read it after step 1 shows a clean string. - If
repr()is clean andexists()is stillFalse, the problem is an access fault: share name, permissions or network reachability.
import os
filepath = '\\machine\c$\Logs\03_filename.log'
print repr(filepath)
print len(filepath)
print os.path.exists(filepath)
Path-building procedure for UNC admin shares
Three literal forms deliver the path intact. Doubling the backslashes and switching to forward slashes have both been confirmed to open the file on this installation.
# Option 1: escape every backslash (four leading for UNC)
filepath = '\\\\machine\\c$\\Logs\\03_filename.log'
# Option 2: forward slashes; the Java file layer maps them on Windows
filepath = '//machine/c$/Logs/03_filename.log'
# Option 3: raw string; backslashes are not decoded
filepath = r'\\machine\c$\Logs\03_filename.log'
When the day prefix is generated at runtime, keep the base path as a raw string and join the parts with os.path. That way no literal ever contains a backslash followed by a digit:
- Define the share root once as a raw string or with forward slashes.
- Build the filename from a formatted date, for example
datetime.now().strftime('%d'), which gives the zero-padded day. - Combine the root and filename with
os.path.join()instead of typing separators by hand. - Open the file in a
withblock so the handle closes even if the read throws.
import os
from datetime import datetime
base = r'\\machine\c$\Logs'
name = datetime.now().strftime('%d') + '_filename.log'
filepath = os.path.join(base, name)
print repr(filepath)
with open(filepath) as f:
data = f.read()
Confirming the file opens from the correct execution scope
A clean repr() and a successful open() in the Script Console prove only that the Designer workstation can reach the share. Ignition runs scripts on different hosts depending on where they are defined:
- Script Console and Designer scripts run on the engineer's PC under the engineer's Windows account.
- Vision client scripts run on the client PC.
- Gateway event scripts, timer scripts and tag change scripts run on the gateway server, under the account the Ignition service uses.
To verify each scope:
- Run the diagnostic block in the Script Console. Confirm
repr()is clean andexists()returnsTrue. - Put the same block in the scope that will run in production, such as a gateway timer script. Send the
repr()andexists()output to the gateway logger instead ofprint. - Check the gateway log. If the Console passed but the gateway returns
False, the Ignition service account has no rights to thec$admin share on the target machine. - Run the script on the first and the last day of the month, or feed the prefix values
01–31in directly. This confirms that no date-generated name reintroduces an escape.
Recurring path pitfalls in Ignition scripts
-
Raw string ending in a backslash.
r'\\machine\c$\Logs\'does not compile, because the final backslash escapes the closing quote. Leave off the trailing separator and letos.path.join()add it. - Paths copied from Windows Explorer. Pasting a path straight into a normal string literal carries every escape hazard in the table above. Paste it into a raw string instead.
-
Paths stored in tags or database rows. Values read at runtime are not decoded, so single backslashes are correct there. Doubling them in the tag gives
\\in the actual path. -
Admin shares.
c$needs local administrator rights on the target PC. A dedicated share with read permission for the gateway service account is easier to keep running than an admin share. -
Unhandled I/O exceptions in gateway scripts. A missing file on a new day, before the log has been created, can throw repeatedly. Wrap the
open()call and log therepr()of the path when it fails.
FAQ
What happens if an Ignition file path contains \n or \t?
Jython replaces \n\tA folder such as\new or \temp then no longer matches any file-system name. Use a raw string, doubled backslashes or forward slashes.
What happens if I use forward slashes for a Windows UNC path in Ignition?
It works. '//machine/c$/Logs/03_filename.log' contains no escape sequences, and the Java file layer under Jython resolves forward slashes on Windows, including UNC paths.
What happens if a raw string file path ends with a backslash?
The script fails to compile, because the final backslash escapes the closing quote even in a raw string. Leave off the trailing separator and build the full path with os.path.join().
What happens if the path works in the Script Console but not in a gateway script?
The string is correct, but the gateway service account cannot reach the share. The Console runs under your Windows login; gateway scripts run under the Ignition service account on the server. Grant that account read access to the share, or use a non-admin share.
When should I contact Inductive Automation support about a file access error?
Contact official support once repr() shows a clean path, os.path.exists() returns True on the gateway host, and open() still fails from gateway scope. Include the full exception, the gateway log excerpt and the Ignition version.