Skip to content
RustPluginGenerator
Runtime errorOxide + Carbon

Fix JsonReaderException when reading an oxide/data file (Unexpected character encountered while parsing value)

Oxide's Newtonsoft serializer hit malformed JSON in a file under oxide/data. The plugin loaded, but the hook that calls DataFileSystem.ReadObject threw. Validate or remove the broken file, then wrap the read in try/catch so a bad file cannot break the hook again.

Server console
Failed to call hook 'OnServerInitialized' on plugin 'HomeTeleport v1.0.0' (JsonReaderException: Unexpected character encountered while parsing value: }. Path 'homes', line 12, position 3.)

Why it happens

Interface.Oxide.DataFileSystem.ReadObject<T> parses the JSON file in oxide/data with Newtonsoft.Json. If the text is not valid JSON, the call throws JsonReaderException and the exception bubbles up through the hook that made the read, which is why the console shows Failed to call hook 'OnServerInitialized' on plugin 'HomeTeleport v1.0.0' (JsonReaderException: ...).

The common triggers are a data file edited by hand (a stray comma, a missing bracket, a truncated object) and a file written while the server was killed or crashed mid-write, leaving a half-written document. The path in the message (Path 'homes') points at the property being read when the parser failed, and line 12, position 3 names the exact spot.

The plugin stays loaded; only that hook call fails, and it fails on every restart until the file is repaired or deleted.

How to fix it

  1. Stop the call path: run oxide.unload HomeTeleport so the plugin stops retrying the read.
  2. Open the file named in the message under oxide/data (for example oxide/data/HomeTeleport.json). Go to the line and position from the error and fix the JSON: remove trailing commas, close every brace and quote, and remove any partial last record.
  3. If the content is not worth repairing, delete the file. The plugin recreates it with defaults on the next save.
  4. Reload with oxide.reload HomeTeleport. A clean load prints Loaded plugin HomeTeleport v1.0.0 by ... and no exception.
  5. Prevent a repeat: catch the exception around the read, log a warning, and fall back to an empty collection so the plugin keeps working. The fixed example below does this.

Before and after

BeforeFails
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;

namespace Oxide.Plugins
{
    [Info("HomeTeleport", "RustPluginGenerator", "1.0.0")]
    [Description("Stores a player's home position and teleports them back to it.")]
    public class HomeTeleport : RustPlugin
    {
        private class StoredData
        {
            public Dictionary<ulong, string> homes = new Dictionary<ulong, string>();
        }

        private StoredData data;

        private void OnServerInitialized()
        {
            // Throws JsonReaderException when oxide/data/HomeTeleport.json is malformed.
            data = Interface.Oxide.DataFileSystem.ReadObject<StoredData>("HomeTeleport");
        }

        [ChatCommand("sethome")]
        private void CmdSetHome(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            data.homes[player.userID.Get()] = player.transform.position.ToString();
            Interface.Oxide.DataFileSystem.WriteObject("HomeTeleport", data);
            SendReply(player, "Home set.");
        }

        [ChatCommand("home")]
        private void CmdHome(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            string saved;
            if (!data.homes.TryGetValue(player.userID.Get(), out saved))
            {
                SendReply(player, "No home set.");
                return;
            }

            player.Teleport(UnityEngine.Vector3.Parse(saved));
            SendReply(player, "Teleported home.");
        }
    }
}
AfterFixed
using UnityEngine;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;

namespace Oxide.Plugins
{
    [Info("HomeTeleport", "RustPluginGenerator", "1.0.0")]
    [Description("Stores a player's home position and teleports them back to it.")]
    public class HomeTeleport : RustPlugin
    {
        private class StoredData
        {
            [JsonProperty("Homes")]
            public Dictionary<ulong, SerializableVector3> Homes = new Dictionary<ulong, SerializableVector3>();
        }

        private class SerializableVector3
        {
            public float x;
            public float y;
            public float z;

            public SerializableVector3() { }

            public SerializableVector3(Vector3 v)
            {
                x = v.x;
                y = v.y;
                z = v.z;
            }

            public Vector3 ToVector3()
            {
                return new Vector3(x, y, z);
            }
        }

        private StoredData data;

        private void OnServerInitialized()
        {
            data = LoadData();
        }

        private StoredData LoadData()
        {
            try
            {
                var loaded = Interface.Oxide.DataFileSystem.ReadObject<StoredData>("HomeTeleport");
                if (loaded != null && loaded.Homes != null) return loaded;
            }
            catch (Exception ex)
            {
                PrintWarning("HomeTeleport.json could not be read and was reset: " + ex.Message);
            }

            // Rebuild the file with a valid, empty document.
            var fresh = new StoredData();
            Interface.Oxide.DataFileSystem.WriteObject("HomeTeleport", fresh);
            return fresh;
        }

        [ChatCommand("sethome")]
        private void CmdSetHome(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            data.Homes[player.userID.Get()] = new SerializableVector3(player.transform.position);
            Interface.Oxide.DataFileSystem.WriteObject("HomeTeleport", data);
            SendReply(player, "Home set.");
        }

        [ChatCommand("home")]
        private void CmdHome(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            SerializableVector3 saved;
            if (!data.Homes.TryGetValue(player.userID.Get(), out saved) || saved == null)
            {
                SendReply(player, "No home set.");
                return;
            }

            player.Teleport(saved.ToVector3());
            SendReply(player, "Teleported home.");
        }
    }
}

FAQ

Can I recover the data instead of deleting it?

Yes, if most of the file is intact. Paste it into a JSON validator, fix the reported line and position, and keep a copy of the original first. When only the last record is truncated, delete that record and close the remaining braces.

Why does the error name OnServerInitialized?

Oxide reports the hook where the exception surfaced, not the line that caused it. The read usually runs in OnServerInitialized or Loaded, so the message names that hook even though the root cause is the file content.

Does the plugin stay loaded after this error?

Yes. Oxide logs the failed hook call and keeps the plugin loaded, and the same hook runs again on the next restart. If the malformed file is never repaired, the error repeats until you fix or remove it.

Different error?

Paste the full console output and get the cause and a fix in plain English.

Open the error explainer

Skip the debugging

Generated plugins are compiled before you get them, and compiler errors are fixed automatically.

Generate a plugin

2 free plugins a month, no card.

Last updated Oct 26, 2026.

Get plugins that compile first time

Generate